题意: 给出一些种类的立方体,每种立方体有无数个,问你用这些立方体最高能堆到多高。限制是放在上面的立方体的长,宽要分别严格小于放在下面的立方体的长,宽。
解法: 一个立方体有长宽高三个属性,索性把一个能旋转立方体拆成6个不能旋转的立方体,然后将立方体排序,做2维偏序的最长上升序列就可以了。
设状态dp[i]为以第i个立方体结尾的最长上升序列长度,那么
dp[i] = max(dp[i], dp[j]+1), 立方体j严格小于立方体i。
/* **********************************************
Author : Nero
Created Time: 2013-8-27 14:10:43
Problem id : UVA 437
Problem Name: The Tower of Babylon
*********************************************** */
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define REP(i,a,b) for(int i=(a); i<(int)(b); i++)
#define clr(a,b) memset(a,b,sizeof(a))
int n;
struct Seg {
int l, r, h;
Seg() {}
Seg(int l, int r, int h) :
l(l), r(r), h(h) {}
bool operator < (const Seg & tt) const {
if(l == tt.l) return r < tt.r;
return l < tt.l;
}
}ss[200];
int tot;
int dp[200];
int main() {
int ca = 0;
while(~scanf("%d", &n), n) {
tot = 1;
int a,b,c;
while(n--) {
scanf("%d%d%d", &a, &b, &c);
ss[tot++] = Seg(a,b,c);
ss[tot++] = Seg(b,a,c);
ss[tot++] = Seg(a,c,b);
ss[tot++] = Seg(c,a,b);
ss[tot++] = Seg(b,c,a);
ss[tot++] = Seg(c,b,a);
}
sort(ss,ss+tot);
int maxn = 0;
for(int i = 1 ; i < tot; i ++) {
dp[i] = 0;
for(int j = 0; j < i; j ++) if(ss[i].l > ss[j].l && ss[i].r > ss[j].r) {
dp[i] = max(dp[i], dp[j] + ss[i].h);
}
maxn = max(maxn, dp[i]);
}
printf("Case %d: maximum height = %d\n", ++ca, maxn);
}
return 0;
}