简单dp
//因为每种规格砖的数量是不限的
//将每块砖转换成3个不同权值得矩形
//就又回到前面的矩形嵌套问题了。
//所以我直接把前面的代码改了一下就提交了。。。。。
//状态转移方程:dp(j)=max(dp(i)+r[j].h)(i为j相连的点)
#include<iostream>
#include<cstring>
using namespace std;
int G[1010][1010];
int d[1010]; //用于记忆已经求出的顶点状最长路径长度
typedef struct //表示矩形的结构体
{
int x;
int y;
int h;
}R;
R r[1100];
int dp(int i,int n) //返回从i出发的最大路径长度
{
int& ans=d[i]; //声明ans为d[i]的引用
if(ans>0) return ans; //d[i]已经计算出来了,直接返回
ans=r[i].h;//初值为第i个矩形的权值
for(int j=1;j<=n;j++)
if(G[i][j])
ans=(ans>dp(j,n)+r[i].h)?ans:(dp(j,n)+r[i].h);
return ans;
}
inline void swap(int &a,int &b)
{
int t;
if(a>b)
{
t=b;
b=a;
a=t;
}
}
int main()
{
int i,j,n,a,b,c,max,k,a1,b1,c1,Case=1;
while(cin>>n&&n)
{
k=0;
for(i=1;i<=n;i++) //矩形编号1--k
{
cin>>a>>b>>c;
a1=a;b1=b;c1=c;
if(a>b) //将一块砖转换成3个带权值的矩形并编号
swap(a,b); //保证宽比长小
r[++k].x=a;r[k].y=b;r[k].h=c;
a=a1;b=b1;c=c1;
if(a>c)
swap(a,c);
r[++k].x=a;r[k].y=c;r[k].h=b;
a=a1;b=b1;c=c1;
if(b>c)
swap(b,c);
r[++k].x=b;r[k].y=c;r[k].h=a;
}
memset(G,0,sizeof(G)); //初始化图的邻接矩阵
memset(d,0,sizeof(d));
for(i=1;i<=k;i++)
for(j=1;j<=k;j++)
if(r[i].x>r[j].x&&r[i].y>r[j].y)
G[i][j]=1; //矩形i可以嵌套j,在图中添加一条边
max=0;
for(i=1;i<=k;i++)
{
int m=dp(i,k);
if(max<m) //对每个顶点找一次最长路径并求其中的最大值、
max=m;
}
cout<<"Case "<<Case++<<": maximum height = "<<max<<endl;
}
return 0;
}