这个题好像以前在UVA上做过。反正就是以前见过这个题。
也是比较简单的dp了。 对于每一种箱子 都有三种方法。 也就是说 每一个边都可以当高。
并且每一种只会使用一次。 所以把一个箱子所能旋转的所有情况都写出来。 存起来。 然后按照 x由大 到小 y由大到小的顺序排序。
排序完 之后 f【i】 = max(f【i】,f【j】 + v【i】)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <fstream>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cmath>
#include <iomanip>
#include <cmath>
typedef long long LL;
typedef unsigned long long LLU;
const double PI=acos(-1.0);
using namespace std;
#define MAXN 1000+10
#define INF 1 << 30
struct Block{
int x,y;
int h;
Block(int a, int b, int c){x = a, y = b, h = c;}
friend bool operator < (Block a, Block b){
if(a.x != b.x)
return a.x > b.x;
else
return a.y > b.y;
}
};
int main (){
int n;
int kase = 0;
while(scanf("%d",&n) && n){
vector <Block> q;
for(int i = 0; i < n; i++){
int a[10];
scanf("%d%d%d",&a[0],&a[1],&a[2]);
sort(a,a+3);
if(a[0] == a[1] && a[1] == a[2])
q.push_back(Block(a[0],a[1],a[2]));
if(a[0] == a[1] && a[1] != a[2]){
q.push_back(Block(a[0],a[1],a[2]));
q.push_back(Block(a[0],a[2],a[1]));
q.push_back(Block(a[2],a[1],a[0]));
}
if(a[0] != a[1] && a[1] != a[2]){
q.push_back(Block(a[0],a[1],a[2]));
q.push_back(Block(a[0],a[2],a[1]));
q.push_back(Block(a[1],a[0],a[2]));
q.push_back(Block(a[1],a[2],a[0]));
q.push_back(Block(a[2],a[0],a[1]));
q.push_back(Block(a[2],a[1],a[0]));
}
}
sort(q.begin(), q.end());
LL f[MAXN] = {0};
int len = q.size();
for(int i = 0; i < len; i++)
f[i] = q[i].h;
for(int i = 0; i < len; i++){
for(int j = 0; j < i; j++){
if(q[i].x < q[j].x && q[i].y < q[j].y)
f[i] = max(f[i], f[j]+q[i].h);
}
}
LL M = 0;
for(int i = 0; i < len; i++)
M = max(M, f[i]);
printf("Case %d: maximum height = %I64d\n",++kase,M);
}
return 0;
}