【HDU 1069 】Monkey and Banana 【 求LIS的思想 DP 】

来源:互联网 发布:同步带周长计算软件 编辑:程序博客网 时间:2024/05/22 17:34

一组研究人员正在设计一项实验,以测试猴子的智商。他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子。如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉。

研究人员有n种类型的砖块,每种类型的砖块都有无限个。第i块砖块的长宽高分别用xi,yi,zi来表示。 同时,由于砖块是可以旋转的,每个砖块的3条边可以组成6种不同的长宽高。

在构建塔时,当且仅当A砖块的长和宽都分别小于B砖块的长和宽时,A砖块才能放到B砖块的上面,因为必须留有一些空间让猴子来踩。

你的任务是编写一个程序,计算猴子们最高可以堆出的砖块们的高度。
Input
输入文件包含多组测试数据。
每个测试用例的第一行包含一个整数n,代表不同种类的砖块数目。n<=30.
接下来n行,每行3个数,分别表示砖块的长宽高。
当n= 0的时候,无需输出任何答案,测试结束。
Output
对于每组测试数据,输出最大高度。格式:Case 第几组数据: maximum height = 最大高度
Sample Input
1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0
Sample Output
Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342

分析 : 虽然题目上说的是每种砖是可以用无限快,但是每种砖只有6中不同的放置方法,题目上还说了,必须要是严格大于才可以放置砖块,所以每一种砖块有用的只有6种罢了。 所以我们可以将每一种的6个形态都存起来。
然后根据砖块的x和y进行排序(这里我定义的时单减得) 。
看代码

#include<cstdio>#include<algorithm>#include<cstring>#define LL long long using namespace std;const int MAXN =1e3+10;const int MAXM =1e6;struct Brick{    int x,y,z;}brick[MAXN];bool cmp(Brick a ,Brick b){    if(a.x==b.x) return a.y>b.y;    return a.x>b.x;}int nsiz;void Add(int x,int y,int z){ // 每种砖的六种形态    brick[++nsiz]={x,y,z};    brick[++nsiz]={x,z,y};    brick[++nsiz]={y,x,z};    brick[++nsiz]={y,z,x};    brick[++nsiz]={z,x,y};    brick[++nsiz]={z,y,x};}int dp[MAXN];//定义dp[i] 表示是以 第i快转为最上层的砖。int main(){    int n;    int ncase=1;    while(scanf("%d",&n)!=EOF&&n){            nsiz=0;        for(int i=1;i<=n;i++) {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            Add(a,b,c);         }         sort(brick+1,brick+1+nsiz,cmp);//       for(int i=1;i<=nsiz;i++){//          printf("x=%d y=%d z=%d\n ",brick[i].x,brick[i].y,brick[i].z);//       }        int maxval=-1;         for(int i=1;i<=nsiz;i++){            dp[i]=brick[i].z;//首先谁都不放,肯定有自身的高度。            for(int j=1;j<i;j++){ // 我们遍历 比它的x和y都高的砖                if(brick[j].x>brick[i].x&&brick[j].y>brick[i].y) // 只有严格大于,才可以将第j快转放在第i快砖的下方                    dp[i]=max(dp[i],dp[j]+brick[i].z);  //  要么还是自身高,要么就是 以第j快砖为最上层的砖的高度+第i块转的高度 高。取最大就好。                maxval=max(maxval,dp[i]);             }         }         printf("Case %d: maximum height = %d\n",ncase++,maxval);     }    return 0;}