題目來源: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其它子問題就是一個或者多個循環的事情
當然 這只是我的一種感受,