nyoj 16-矩形嵌套(贪心 + 动态规划DP)
16-矩形嵌套
内存限制:64MB
时间限制:3000ms
Special Judge: No
accepted:13
submit:28
题目描述:
有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。
输入描述:
第一行是一个正正数N(0<N<10),表示测试数据组数, 每组测试数据的第一行是一个正正数n,表示该组测试数据中含有矩形的个数(n<=1000) 随后的n行,每行有两个数a,b(0<a,b<100),表示矩形的长和宽
输出描述:
每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行
样例输入:
1 10 1 2 2 4 5 8 6 10 7 9 3 1 5 8 12 10 9 7 2 2
样例输出:
5
分析:
贪心 + 动态规划
步骤:
①、根据宽度、长度的优先级进行由小到大的排序(贪心)
②、从前到后遍历每一个节点(k),而对应与该节点的最大值情况是根据前面(k-1)个节点确定的
③、根据状态方程 dp[i] = max(dp[i], dp[j] + 1); 对满足条件的每一个点进行求值
核心代码:
1 for(int i = 0; i < n; ++ i) 2 { 3 dp[i] = 1; 4 for(int j = 0; j < i; ++ j) 5 { 6 dp[i] = max(dp[i], dp[j] + 1); 7 } 8 } 9 printf("%d\n", dp[n-1]); //dp[n-1]即为最多个数
C/C++代码实习(AC):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <stack> 7 #include <map> 8 #include <queue> 9 10 using namespace std; 11 const int MAXN = 1010; 12 int dp[MAXN]; 13 struct node 14 { 15 int w, l; // w宽,l长 16 }P[MAXN]; 17 18 bool cmp(node a, node b) 19 { 20 if(a.w != b.w) return a.w < b.w; 21 return a.l < b.l; 22 } 23 24 int main() 25 { 26 int t, a, b, n; 27 scanf("%d", &t); 28 while(t --) 29 { 30 scanf("%d", &n); 31 for(int i = 0; i < n; ++ i) 32 { 33 scanf("%d%d", &a, &b); 34 P[i].w = min(a, b); // 前几次一直wr,结果才是因为左边的不一定就是宽 35 P[i].l = max(a, b); 36 } 37 38 sort(P, P+n, cmp); 39 for(int i = 0; i < n; ++ i) 40 { 41 dp[i] = 1; 42 for(int j = 0; j < i; ++ j) 43 { 44 if(P[j].l < P[i].l && P[j].w < P[i].w) 45 dp[i] = max(dp[i], dp[j] + 1); 46 } 47 } 48 printf("%d\n", dp[n-1]); 49 } 50 return 0; 51 }