最简单的DAG了,只需要排个序,dp【i】 代表以第i个为结尾可以堆成的最大高度。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <queue>
#include <list>
#include <cmath>
using namespace std;
#define cir(a,b) memset(a,b,sizeof a)
typedef long long LL;
const int maxn = 10000+10;
const int INF = 1e9+10;
int n;
struct Brick
{
int l,w,h;
}s[maxn];
int dp[maxn];
bool cmp(const Brick& t1,const Brick& t2)
{
if(t1.l==t2.l) return t1.w<t2.w;
else return t1.l<t2.l;
}
int kase;
int main()
{
kase = 1;
while(cin >> n && n)
{
cir(dp,0);
int E = 1;
int l,w,h;
for(int i=0;i<10000;i++)
{
s[i].h = 0;
}
for(int i=1;i<=n;i++)
{
cin >> l >> w >> h;
s[E].l = l,s[E].w = w,s[E++].h = h;
s[E].l = l,s[E].w = h,s[E++].h = w;
s[E].l = w,s[E].w = l,s[E++].h = h;
s[E].l = w,s[E].w = h,s[E++].h = l;
s[E].l = h,s[E].w = l,s[E++].h = w;
s[E].l = h,s[E].w = w,s[E++].h = l;
}
//cout << "E : " << E <<endl;
sort(s+1,s+E+1,cmp);
int Max = -1;
for(int i=1;i<=E;i++) dp[i] = s[i].h;
for(int i=1;i<=E;i++)
{
for(int j=1;j<=i;j++)
{
if(s[i].l > s[j].l && s[i].w > s[j].w)
{
dp[i] = max ( dp[i],dp[j]+s[i].h );
}
}
Max = max( dp[i],Max );
//cout << s[i].l << " " << s[i].w << " " << s[i].h << " " <<endl;
}
printf("Case %d: maximum height = ",kase++);
cout << Max << endl;
//cout << H <<endl;
}
return 0;
}