您的位置:首页 > 编程语言 > C语言/C++

nyoj16 矩形嵌套

2016-05-05 08:06 190 查看
题目来源: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其它子问题就是一个或者多个循环的事情

当然 这只是我的一种感受,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  学习 竞赛 编程 c语言