嵌套矩形问题
问题描述:
有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;
}