Description
有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。
Input
第一行是一个正正数N(0<N<10),表示测试数据组数,
每组测试数据的第一行是一个正正数n,表示该组测试数据中含有矩形的个数(n<=1000)
随后的n行,每行有两个数a,b(0<a,b<100),表示矩形的长和宽
Output
每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行
Sample Input Copy
1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2
Sample Output Copy
5
思路
对于任意两个矩形A,B如果A嵌套在B内,那么B一定不会嵌套在A内,所以如果将一个个矩形视为节点的话,那么矩形间的嵌套关系可以用一张有向无环图表示,故此题可以抽象成一个DAG最长路问题,数组dp[]的第 i 个元素dp[i]表示从第 i 个矩形开始所能嵌套的最多的矩形个数,故可以写出如下状态转移方程:。
代码(C++)
#include <iostream>
#include <cmath>
#include <cstring>
#define MAXN 1005
using namespace std;
struct rect{
int l, w;
}rects[MAXN];
int dp[MAXN], n, T, res;
int DP(int i){
if(dp[i] > 0)return dp[i];
for(int j = 0; j < n; j++){
if((rects[i].l < rects[j].l && rects[i].w < rects[j].w) || (rects[i].l < rects[j].w && rects[i].w < rects[j].l)){
dp[i] = max(dp[i], DP(j) + 1);
if(dp[i] > res)res = dp[i];
}
}
return dp[i];
}
int main(){
scanf("%d", &T);
while(T--){
memset(dp, 0, sizeof(dp));
res = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d%d", &rects[i].l, &rects[i].w);
}
DP(0);
printf("%d\n", res + 1);
}
return 0;
}