题目:这里
题意:
Description
一组研究人员正在设计一项实验,以测试猴子的智商。他们将挂香蕉在建筑物的屋顶,同时,提供一些砖块给这些猴子。如果猴子足够聪明,它应当能够通过合理的放置一些砖块建立一个塔,并爬上去吃他们最喜欢的香蕉。
研究人员有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
一种砖虽然有无数个,最多用两个,因为从小往上看是递减的,下面的只能大于上面,连等于都不行,长宽高三个性质,全排列有六种,将所有砖块的这六种排列排序
,长从大到小,如果长相等,就按宽从大到小,这样排序之后,就变成了求最大单调子序列了。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<string> 7 using namespace std; 8 9 struct node{ 10 int h,v,l; 11 }re[200]; 12 int dp[200]; 13 14 int max(int x,int y) {return x>y?x:y;} 15 16 bool cmp(node a,node b) 17 { 18 if (a.l==b.l) 19 { 20 if (a.v==b.v) 21 return a.h>b.h; 22 return a.v>b.v; 23 } 24 return a.l>b.l; 25 } 26 27 int main() 28 { 29 int n,tem=0; 30 while (~scanf("%d",&n)&&n) 31 { 32 int cas=0; 33 for (int i=1 ; i<=n ; i++) 34 { 35 int x,y,z; 36 scanf("%d%d%d",&x,&y,&z); 37 re[++cas].l=x,re[cas].h=y,re[cas].v=z; 38 re[++cas].l=z,re[cas].h=y,re[cas].v=x; 39 re[++cas].l=x,re[cas].h=z,re[cas].v=y; 40 re[++cas].l=y,re[cas].h=z,re[cas].v=x; 41 re[++cas].l=z,re[cas].h=x,re[cas].v=y; 42 re[++cas].l=y,re[cas].h=x,re[cas].v=z; 43 } 44 sort(re+1,re+cas+1,cmp); 45 for (int i=1 ; i<=cas ; i++) 46 { 47 dp[i]=re[i].h; 48 for (int j=1 ; j<i ; j++) 49 { 50 if (re[i].l<re[j].l&&re[i].v<re[j].v) 51 dp[i]=max(dp[i],dp[j]+re[i].h); 52 } 53 } 54 int ans=0; 55 for (int i=1 ; i<=cas ; i++) 56 ans=max(ans,dp[i]); 57 printf("Case %d: maximum height = %d\n",++tem,ans); 58 } 59 return 0; 60 }