nyoj16 矩形嵌套

题目来源:http://acm.nyist.net/JudgeOnline/problem.php?pid=16

矩形嵌套

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
描述
有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
来源
经典题目
上传者
张云聪


这题应该能用贪心做,我试了下, 很多测试数据都能过,除开排序,只有O(n)的时间,但是提交就一直WA,后来还是用动态规划吧

也不去纠结贪心算法为啥错了。

思路也简单,先升序排序,然后从 i 开始dp,去寻找在它之前的矩形当中,它能够嵌套的矩形 b,如果发现,那么它能嵌套的最大值 

max(矩形b嵌套最大值,,自身最大值)。


# include <stdio.h>
# include <iostream>
# include <algorithm>
using namespace std;
int dp[1005];
struct nod{
int length;
int width;
} rectangle[1001];
bool compare(nod a,nod b)
{
      return a.length < b.length || a.length == b.length && a.width < b.width;   
}


void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}


int main()
{
int N, n, i, j, count;
freopen("in.txt", "r", stdin);
scanf("%d", &N);
while(N--){
scanf("%d", &n);
count = 1;
for(i = 0; i < n; i++){
scanf("%d %d", &rectangle[i].length, &rectangle[i].width);
if(rectangle[i].length < rectangle[i].width) swap(&rectangle[i].length, &rectangle[i].width);
}
sort(rectangle, rectangle + n, compare);
for(i = 0; i < n; i++){
dp[i] = 1;
for(j = 0; j < i; j++){
//算法核心 当只有一个矩形的时候 默认值为1,重复计算子问题的解,1 - n个矩形有1 - n 子问题, 
if(rectangle[i].length > rectangle[j].length && rectangle[i].width > rectangle[j].width) {
//这一层循环为什么要从0开始? 因为可能与i 最接近的 i - 1这个矩形不能嵌套 
//如果 矩形 i 能够嵌套矩形 j 那么矩形 i 的最大嵌套量就应该是 矩形j + 1 和 矩形 i 之间的最大值 
dp[i] = max(dp[i],dp[j]+1);
}
}
count = max(dp[i], count);
}
printf("%d\n", count);

return 0;
}


我现在觉得动态规划最重要的就是把子问题区分出来,只要找到怎样去求一个子问题,然后dp其它子问题就是一个或者多个循环的事情

当然 这只是我的一种感受,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章