经典的dp问题,给出n种类型的长方体石块,给出每种的长、宽、高,每种石块有三种摆放方式,数量不限,可以累加着往上放,问最多能放多高?但是有个限定条件,下边的面积一定要大于上边的面积,长和宽必须均小于下面石块的长和宽才能放上去。
分析:
先对面积进行排序,每种石块可以有不同的摆放方式,这样就意味着可以看做不同的石块;按面积从大到小进行排序,然后还要满足下面的长和宽都要大于上面的长和宽。若不排序,则关系对应不起来。再确定最大的那个面积的石块为dp[0],然后利用dp思想逐层求解。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct _data
{
int x,y,z,area;//定义结构体;
};
_data data[200];
bool com(_data d1,_data d2)
{
return d1.area<d2.area;//排序标准
}
int n;
int dp[200];
int main()
{
int count=1;
while(scanf("%d",&n)!=EOF&&n)
{
int index=0;
for(int i=0;i<n;i++)
{//不同的摆放方式
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
data[index].x=x;data[index].y=y;data[index].z=z;data[index++].area=x*y;
data[index].x=y;data[index].y=x;data[index].z=z;data[index++].area=x*y;
data[index].x=y;data[index].y=z;data[index].z=x;data[index++].area=z*y;
data[index].x=z;data[index].y=y;data[index].z=x;data[index++].area=z*y;
data[index].x=x;data[index].y=z;data[index].z=y;data[index++].area=x*z;
data[index].x=z;data[index].y=x;data[index].z=y;data[index++].area=x*z;
}
sort(data,data+index,com);//首先需要对面积排序
memset(dp,0,sizeof(dp));
dp[0]=data[0].z;
for(int i=1;i<index;i++)
{
int temp=0;
for(int j=0;j<i;j++)
if(data[i].x>data[j].x && data[i].y>data[j].y&&temp<dp[j])
temp=dp[j];//满足条件才行,更新最大值;
dp[i]=temp+data[i].z;//写出更新的dp[i]
}
int ans=dp[0];
for(int i=1;i<index;i++)
ans=max(ans,dp[i]);//看哪个最大;
printf("Case %d: maximum height = %d\n",count++,ans);
}
return 0;
}