DAG上的动态规划

嵌套矩形问题

问题描述:

有n个矩形,每个矩形可以用两个整数a,b描述,表示它的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d,或者b<c,a<d(相当于把矩形X旋转90°)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)内。你的任务是选出尽可能多的矩形排成一行。使得除了最后一个之外,每个矩形都可以嵌套在下一个矩形内。

测试用例:

1//用例组数

6 //矩形个数 
3 4 //每个矩形的长和宽 
2 5 
1 2 
5 6 
4 5 
4 5

【代码】

#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
int G[maxn][maxn], n, d[maxn];
struct tri
{
	int length;
	int width;
};
tri rec[maxn];
void createGraph()//建图
{
	memset(G, 0, sizeof(G));
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (rec[i].length > rec[j].length&&rec[i].width > rec[j].width)//可以嵌套时
				G[i][j] = 1;//构造一条有向边从i-->j
}
int dp(int i)//从i开始,该点能有几个嵌套矩形
{
	int& ans = d[i];//简化读写操作
	if (ans > 0)return ans;//当d[i]>0说明已经计算过,直接返回即可
	ans = 1;//否则从1开始算
	for (int j = 0; j < n; j++)//遍历每个点
	{
		if (G[i][j])//如果i到j可以嵌套
		{
			int temp = dp(j);//那么递归,询问点j能嵌套几个矩形
			ans = ans>temp + 1 ? ans : temp + 1;//遍历结束后,得到最多可嵌套的矩形,存入ans(d[i]的引用)中
		}
	}
	return ans;//返回答案
}
int main()
{
	int N;
	scanf("%d", &N);
	while (N-->0)
	{
		int ans = 0;
		scanf("%d", &n);
		for (int i = 0; i<n; i++) {
			int tmp1, tmp2;
			scanf("%d%d", &tmp1, &tmp2);
			rec[i].length = tmp1>tmp2 ? tmp1 : tmp2;//数据整理,长的为长,短的为宽,方便建图
			rec[i].width = tmp1<tmp2 ? tmp1 : tmp2;
		}
		createGraph();

		//初始化记忆数组 
		memset(d, 0, sizeof(d));
		for (int i = 0; i<n; i++) //遍历所有端点,能组成最长的嵌套矩形为答案
		{
			int tmp = dp(i);
			ans = ans>tmp ? ans : tmp;
		}
		printf("%d\n", ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/waterboy_cj/article/details/81103479
今日推荐