HDU 1069

来源:互联网 发布:青铜器乐队知乎 编辑:程序博客网 时间:2024/05/16 08:54
 

题目要求是 , 把给定尺寸的长方体 ( 数量不限 ) 叠在一起 , 能叠加的条件是 , 上面一个长方体的长宽比下面一个长方体的长宽短都短 , 或者一边相等 , 另一边较短 , 长方体可以任意面朝下摆放 , 求这些长方体能够叠成的最高的高度 .

不难看出 , 这题和最长递减子序列很相似 . 可以用类似的思路求解 .

首先对各种尺寸的长方体不同面朝下的各种摆法按照地面的长宽和面积排序 , 排序后 , 保证排在前面的长方体的底面的长和宽都比下一个的要长 , 或者一边相等 , 另一边较长 , 并且前面的长方体的面积必定比后面的大 .

设 h[i] 为前 i 个长方体中 , 包含第 i 个长方体的能够摆放的最大高度 ,z[i] 为第 i 个长方体的高 , 其转移方程为 :

h[i]=max(h[k])+z[i](1<=k<i, 且第 i 个长方体能摆在第 k 个长方体之上 )

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{
int x;
int y;
int z;
int s;
}tt[100];
bool cmp(node a,node b)
{
return a.s<b.s;
}
int judge(node a,node b)
{
if((a.x>b.x&&a.y>b.y)||(a.x>b.y&&a.y>b.x))
return 1;
return 0;
}
int main()
{
int n,i,j,k,res,max,cas=0;
int a[3],sum[100];
int d[3][3]={{0,1,2},{0,2,1},{2,1,0}};
while(scanf("%d",&n)&&n)
{
cas++;
memset(sum,0,sizeof(sum));
for(i=0,k=0;i<n;i++)
{
scanf("%d%d%d",&a[0],&a[1],&a[2]);
for(j=0;j<3;j++)
{
tt[k].x=a[d[j][0]];
tt[k].y=a[d[j][1]];
tt[k].z=a[d[j][2]];
tt[k].s=tt[k].x*tt[k].y;
k++;
}
}
sort(tt,tt+k,cmp);
/*for(i=0;i<k;i++)
printf("%d ",tt[i].s);*/
sum[0]=tt[0].z;
for(i=1;i<k;i++)
{
res=0;
for(j=0;j<i;j++)
{
if(sum[j]>res&&judge(tt[i],tt[j]))
res=sum[j];
}
sum[i]=res+tt[i].z;
}
for(i=0,max=-1;i<k;i++)
if(max<sum[i])
max=sum[i];
printf("Case %d: maximum height = %d\n",cas,max);
}
}