把每个立方体分成是3个,前两个参数(x<=y)表示上表面,第三个表示高h。
然后按照上表面的边长由小到大排序,则原题就变成了最大上升子序列问题(LIS)。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#define fir first
#define sed second
#define MP makepair
using namespace std;
typedef unsigned long long LLU;
typedef pair<LLU, LLU> pii;
struct Node
{
pii p;
LLU h;
Node(LLU a, LLU b, LLU h):p(a, b), h(h) {}
bool operator < (const Node & a)const
{
return p.fir<a.p.fir && p.sed<a.p.sed;
}
};
int cmp(const Node & a, const Node & b)
{
return a.p<b.p;
}
vector<Node> v;
LLU d[1111];
int main()
{
int n, kase=0;
while(cin>>n && n)
{
LLU a[3];
v.clear();
while(n--)
{
for(int i=0; i<3; i++)
cin>>a[i];
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(), cmp);
for(int i=0; i<v.size(); i++)
d[i]=v[i].h;
for(int i=0; i<v.size(); i++)
for(int j=i+1; j<v.size(); j++)
if(v[i]<v[j])
d[j]=max(d[j], d[i]+v[j].h);
LLU ans=0;
for(int i=0; i<v.size(); i++)
ans=max(ans, d[i]);
cout<<"Case "<<++kase<<": maximum height = "<<ans<<endl;
}
return 0;
}