首页 > 代码库 > ZOJ 1093

ZOJ 1093

排序DP(相当于最长不下降子序列) 

如果把一块砖块的所有6种摆放方式转化为6种不同的砖块; 

即相当于有6n种砖块,然后按照一个方向从大到小排序; 

再依次检查每一块与其下面的所有砖块是否满足摆放条件; 

将每一块砖块放到塔中能够获得的最大高度记录到数组height[N]中; 

则该数组中的最大值就是该题的解了;

 

#include <iostream>
#include <algorithm>
#include "cstdio"
using namespace std;
#define maxi 200
struct Block{
    int x,y,h;
    void init(int xx,int yy,int hh){
        x=xx;
        y=yy;
        h=hh;
    }
}b[maxi];
int dp[maxi];
int cmp(Block a,Block c)
{
    return a.x>c.x;
}
int max(int a,int c){
    return a>c?a:c;
}
int main(){
    int n,x,y,h,m,game=0;
    freopen("test.txt","r",stdin);
    while(cin>>n){
        if(n==0)break;
        m=0;
        for(int i=0;i<n;i++){
            cin>>x>>y>>h;
            b[m++].init(x,y,h);
            b[m++].init(h,x,y);
            b[m++].init(y,h,x);
            b[m++].init(y,x,h);
            b[m++].init(x,h,y);
            b[m++].init(h,y,x);
        }
        sort(b,b+6*n,cmp);
        for(int i=0;i<n*6;i++){
            dp[i]=b[i].h;
        }
        int ma=0;
        for(int i=1;i<n*6;i++){
            int ans=0;
            for(int j=i-1;j>=0;j--){
                if(b[i].x<b[j].x&&b[i].y<b[j].y&&ans<dp[j])
                    ans=dp[j];
            }
            dp[i]+=ans;
            if(ma<dp[i])ma=dp[i];
        }
        cout<<"Case "<<++game<<": maximum height = "<<ma<<"\n";
    }
    return 0;
}