点击此链接打开题目
题目大意:给出n种方块,每种方块有无限个,且每个方块可以以任意边作为长、宽、高。要求将这些方块摆成一摞,且要满足上面的方块的长小于下面方块的长、上面的方块的宽小于下面方块的宽,求这些方块能摆放的最高高度。
题目解析:
1:因为每个方块可以以任意边作为长、宽、高(x、y、z),所以每种方块有6种不同的摆放形式。为了简化问题,我们将其看作6种不同类型的方块;
2:若要满足题意,每种类型的方块最多有一个;
3:若要满足题意,则从下到上x和y都必须是递减的,所以可以先按x的大小对所有方块排序,从而简化问题;
4:按x的大小排序后,可以用动态规划的方法从下到上依次求出每一个方块可以到达的最高高度。此时令每个方块的z值表示其最大高度。其状态压缩方程为:block[i].z=block[i].z+max(block[j].z)(j∈[1,i-1]&&block[j].x>block[i].x&&block[j].y>block[i].y)。其中block[]为表示每个方块x、y、z的结构体类型数组;
5:找出所有方块z值的最大值就是所求结果。
下面是AC了的代码(注释比较详细):
#include <iostream> #include <algorithm> using namespace std; //建立方块结构体 struct node { int x,y,z;//方块的长、宽、高 }block[185];//30*6=180 //按x值比较两个方块的大小 bool cmpx(node a,node b) { return a.x>b.x; } int main() { int n;// 每组数据有n种方块; int T=1;//测试数据的组数 while(cin>>n&&n) { int a,b,c;//表示长、宽、高 int num=0;//表示不同方块的数目 for(int i=0;i<n;i++) { cin>>a>>b>>c; //每种方块有6种不同的放置形态 num++;block[num].x=a;block[num].y=b;block[num].z=c; num++;block[num].x=a;block[num].y=c;block[num].z=b; num++;block[num].x=b;block[num].y=a;block[num].z=c; num++;block[num].x=b;block[num].y=c;block[num].z=a; num++;block[num].x=c;block[num].y=a;block[num].z=b; num++;block[num].x=c;block[num].y=b;block[num].z=a; } //按x的值对所有方块排序 sort(block+1,block+num+1,cmpx); //从第一层开始,求出每一层方块可以到达的最高高度 for(int i=1;i<=num;i++) { int Max=0;//第i层下面的最高高度 for(int j=i-1;j>=1;j--) { if(block[i].x<block[j].x&&block[i].y<block[j].y&&block[j].z>Max) Max=block[j].z; } block[i].z+=Max; } //寻找可到达高度最高的方块的高度 int Max=0; for(int i=1;i<=num;i++) if(Max<block[i].z) Max=block[i].z; cout<<"Case "<<T++<<": maximum height = "<<Max<<endl; } return 0; }