ZOJ 1093 Monkey and Banana (LIS)解题报告
ZOJ 1093 Monkey and Banana (LIS)解题报告
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87125#problem/B
题目:
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
题目大意:
有N块已知长、宽、高的砖,每种砖的数量不限,将砖摞起来,使在上面的砖的长宽都小于下面的(不能等于),求能堆成的最大高度。
分析:
LIS问题。动态规划dp。
由于砖块可以旋转,那么给一块砖就相当于给了三块砖(即N<=30*3)。
求从编号 i 出发能堆出的最大高度(不包括砖块),dp(i) = max(dp(j) + j的高度; j是能放在i上面的砖块编号),将开始节点看成地板最大高度为无穷大,为dp(0);
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<climits> //用INT_MAX 4 using namespace std; 5 const int M=100; 6 7 int box[M][3]; 8 int height[M]; 9 int number; 10 11 //互换长宽高,转换砖块的三种类型 12 void change(int index,int a,int b,int c) 13 { 14 box[index][0]=a; 15 box[index][1]=b; 16 box[index][2]=c; 17 } 18 19 int dp(int j) 20 { 21 int& ans=height[j]; 22 if(ans!=-1) //搜索过的直接返回 23 return ans; 24 for(int i=1;i<=number;i++)//搜索每一层 25 { 26 if(i!=j) 27 { 28 if((box[i][0]<box[j][0]&&box[i][1]<box[j][1])||(box[i][1]<box[j][0]&&box[i][0]<box[j][1])) 29 { 30 int temp=dp(i)+box[i][2]; 31 if(temp>ans) 32 ans=temp; 33 } 34 } 35 } 36 if(ans==-1)//最后一层未更新 37 ans=0; 38 return ans; 39 } 40 41 int main() 42 { 43 int n; 44 int m=1; 45 while(scanf("%d",&n)&&n) 46 { 47 int a,b,c; 48 number=0; 49 box[0][0]=box[0][1]=box[0][2]=INT_MAX;//地板看成无穷大砖块 50 for(int i=1;i<=n;i++) 51 { 52 scanf("%d%d%d",&a,&b,&c); 53 change(++number,a,b,c); 54 change(++number,b,c,a); 55 change(++number,c,a,b); 56 } 57 for(int i=0;i<=number;i++) 58 { 59 height[i]=-1; 60 } 61 printf("Case %d: maximum height = %d\n",m++,dp(0)); 62 } 63 return 0; 64 }
每次都想完全自己写,可是自己写的都有很多错误,最后有看了别人的博客。