矩形嵌套 ————DAG(有向無環圖)上的動態規劃

矩形嵌套

時間限制: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


矩形嵌套問題。

因爲一個矩形無法直接或間接的嵌套在自己內部。所以叫有向無環圖。

任務是求有向無環圖的最長路徑,可以用d(i)來表示從結點i出發的最長路長度,第一步只能走到它的相鄰點假設爲 j,

因此                    d(i) = max{d(j) + 1  (i, j) ∈ E (邊集)}

這樣的話,我們可以嘗試用記憶化搜索的方式來計算上式。

但是我們應該先把圖建立出來,用鄰接矩陣來表示,然後就記憶化搜索。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#define MAXN 1010
using namespace std;

int x[MAXN], y[MAXN], G[MAXN][MAXN],d[MAXN];
int n;

int dp(int i)
{
    int& ans = d[i]; // ans 是一個引用,對ans操作就是對d[i]操作
    if(ans > 0) return ans; // 如果已經搜索過直接返回,減少搜索次數。
    ans = 1;    //如果沒有搜索,最小值爲1 即就它自己可以嵌套。
    for(int j = 0; j < n; j++)
    {
        if(G[i][j])
            ans = max(ans, dp(j) + 1);//判斷動歸方程,記憶化搜索
    }
    return ans;
}

int main()
{
    int t, ans, i, j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(i = 0; i < n; i++)
        {
            scanf("%d%d",&x[i],&y[i]);
            if(x[i] > y[i])
            {
                int k;
                k = y[i];
                y[i] = x[i];
                x[i] = k;
            }
        }
        memset(G, 0, sizeof(G));
        for(i = 0; i < n; i++)
        {
            for(j = 0; j < n; j++)
            {
                if(x[i] < x[j] && y[i] < y[j])
                    G[i][j] = 1;  // G爲鄰接矩陣,G[i][j]表示第i個矩陣可以嵌套在第 j個矩陣裏面
            }
        }
        memset(d,0,sizeof(d)); // d數組記錄的是每個矩陣能嵌套的最大矩陣
        ans = 0; 
        for(i = 0; i < n; i++)
        {
            if(dp(i) > ans)
                ans = dp(i);
        }
        printf("%d\n",ans);
    }
    return 0;
}


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