这道题是典型的dp题。首先是数据的处理上,因为每个长方体的3条不同长度的棱都可以作为高,因此一个长方体可以看成3个不同的长方体。从而将数据扩展为3*n,然后将所有的长方体以长度为第一排序条件,宽度为第二排序条件进行排序。接着整个问题就变成了求最长递减子序列的问题了,多得到的状态方程为:dp[i]=max{dp[i],dp[j]+blocks[i].z}.其中dp[i]是以第i块木块为最顶上的木块时多得到的最大高度,即最优子结构。最后找到最最优的子结构即为本题的最大高度。
#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"string.h"
#include"cmath"
#include"queue"
#define mx 1005
using namespace std;
struct node
{
int x,y,z;
}blocks[mx];
int n,dp[mx];
bool cmp(const node a,const node b) //以长为第一要求,宽为第二要求进行排序
{
if(a.y!=b.y) return a.y>b.y;
else return a.x>b.x;
}
int main()
{
int count1=;
while(cin>>n,n)
{
count1++;
int i,j,k;
for(j=,i=;i<n;i++) //将一个木块变成3个
{
int a,b,c;
cin>>a>>b>>c;
blocks[j].x=min(a,b);
blocks[j].y=max(a,b);
blocks[j++].z=c;
blocks[j].x=min(a,c);
blocks[j].y=max(a,c);
blocks[j++].z=b;
blocks[j].x=min(b,c);
blocks[j].y=max(b,c);
blocks[j++].z=a;
}
k=j;
sort(blocks,blocks+k,cmp);//排序
int maxhigh=;//记录最长上升子序列的长度
for(i=;i<k;i++)
{
dp[i]=blocks[i].z;//对dp[]进行初始化
for(j=;j<i;j++)
{
if(blocks[j].x>blocks[i].x&&blocks[j].y>blocks[i].y&&dp[j]+blocks[i].z>dp[i])//判断条件缺一不可
{
dp[i]=dp[j]+blocks[i].z;
}
}
if(dp[i]>maxhigh) maxhigh=dp[i];
}
cout<<"Case "<<count1<<": maximum height = "<<maxhigh<<endl;
}
return ;
}