HDU 1069 Monkey and Banana Dp問題

題目鏈接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68966#problem/C

題意:給定一些長方體的尺寸,數量都是無限個,然後求這寫長方體能堆切成的最大高度。PS:接觸面的上面必須嚴格小於下面的面。

這題和紫書P269的巴比倫塔例題差不多,可以說是一模一樣,紫書上把這種題型叫DAG上最長路。看了別人的代碼AC的。

思路:把所有長方體的狀態枚舉出來,然後排序(假設爲大邊在前,小邊在後),這樣一來。用dp[i]表示以狀態i結束的最大高度,這dp[i]只能由其前面的狀態轉移得到。所以枚舉前面的狀態,O(N^2)解決。


代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

struct node{
    int x,y,z;
    bool operator<(const node &a)const{
        if(x!=a.x) return x>a.x;
        return y>a.y;
    }
}S[200];

int N,tot,dp[200];

int main(){
    //freopen("in.txt","r",stdin);
    int kase=0;
    while(cin>>N && N){
        kase++;tot=0;
        int a,b,c;
        for(int i=0;i<N;i++){
            scanf("%d %d %d",&a,&b,&c);//存儲所有狀態
            S[tot++]=(node){a,b,c};if(a!=b) S[tot++]=(node){b,a,c};
            S[tot++]=(node){a,c,b};if(a!=c) S[tot++]=(node){c,a,b};
            S[tot++]=(node){b,c,a};if(b!=c) S[tot++]=(node){c,b,a};
        }
        sort(S,S+tot);//狀態排序
        memset(dp,0,sizeof(dp));
        int ans=S[0].z;
        for(int i=0;i<tot;i++){//枚舉終點狀態
            dp[i]=S[i].z;
            for(int j=0;j<i;j++)//枚舉轉移中介狀態
                if(S[j].x>S[i].x && S[j].y>S[i].y)
                    dp[i]=max(dp[i],dp[j]+S[i].z);
            if(dp[i]>ans) ans=dp[i];
        }
        printf("Case %d: maximum height = %d\n",kase,ans);
    }
    return 0;
}


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