题目大意
有n种长宽高为x,y,z的砖头,每种都有无数个。
砖头可以用不同姿势的方向来盖。
砖头a以某种姿势可以盖在砖头b上,当且仅当a的底部的长宽都要比b的底部长宽要小。
问最高可以建多高?
思路:按图论的最长路dp也可,用 LIS也可以也就相当于把DAG拓扑排序了一下
//0 KB 19 ms
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{int a,b,h;}block[100];
int n;
int dp[100];
void add_block(int x,int a,int b,int h)
{
block[x].a=a;
block[x].b=b;
block[x].h=h;
}
bool ok(int x,int y)
{
if(block[x].a>block[y].a&&block[x].b>block[y].b) return true;
if(block[x].b>block[y].a&&block[x].a>block[y].b) return true;
return false;
}
int memrize(int x)
{
int &ans=dp[x];
if(ans>0) return ans;
ans=block[x].h;
for(int i=1;i<=3*n;i++){
if(ok(x,i)) ans=max(ans,memrize(i)+block[x].h);
}
return ans;
}
void print(int x){ //调试检验打印方案
printf("(%d %d %d)\n",block[x].a,block[x].b,block[x].h);
for(int i=1;i<=3*n;i++) if(ok(x,i)&&dp[x]==dp[i]+block[x].h) {
print(i);
break;
}
}
int main()
{
int cnt=0;
while(scanf("%d",&n),n){
int a,b,c;
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a,&b,&c);
add_block(i,a,b,c);
add_block(i+n,a,c,b);
add_block(i+2*n,b,c,a);
}
int ans=-(1<<30);
memset(dp,-1,sizeof(dp));
for(int i=1;i<=3*n;i++)
ans=max(ans,memrize(i));
printf("Case %d: maximum height = %d\n",++cnt,ans);
}
return 0;
}