题目来源:http://acm.nyist.net/JudgeOnline/problem.php?pid=16
矩形嵌套
-
描述
- 有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。
这题应该能用贪心做,我试了下, 很多测试数据都能过,除开排序,只有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其它子问题就是一个或者多个循环的事情
当然 这只是我的一种感受,