方程f[i]=max(f[i],f[j]+h[i])。
//
// main.cpp
// Richard
//
// Created by 邵金杰 on 16/9/9.
// Copyright © 2016年 邵金杰. All rights reserved.
//
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=35;
struct node{
int x,y,z;
node(int x=0,int y=0,int z=0): x(x),y(y),z(z) {}
bool operator < (const node &e) const{
if(x!=e.x) return x<e.x;
else if(y!=e.y) return y<e.y;
else return z<e.z;
}
};
int ff[maxn*3];
int main()
{
int n;
int kase=0;
while(scanf("%d",&n)&&n)
{
vector<node> v;
memset(ff,0,sizeof(ff));
int a[3];
for(int i=0;i<n;i++)
{
scanf("%d%d%d",&a[0],&a[1],&a[2]);
sort(a,a+3);
v.push_back(node(a[0],a[1],a[2]));
v.push_back(node(a[0],a[2],a[1]));
v.push_back(node(a[1],a[2],a[0]));
}
sort(v.begin(),v.end());
int MAX=0;
for(int i=0;i<v.size();i++) ff[i]=v[i].z;
for(int i=0;i<v.size();i++)
{
for(int j=0;j<i;j++)
{
if(v[i].x>v[j].x&&v[i].y>v[j].y){
ff[i]=max(ff[i],ff[j]+v[i].z);
}
MAX=max(MAX,ff[i]);
}
}
cout<<"Case "<<++kase<<": maximum height = "<<MAX<<endl;
}
return 0;
}