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其它子問題就是一個或者多個循環的事情

當然 這只是我的一種感受,

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