这道题可以看作一个DAG(有向无环图)上的DP。
不幸贡献一个WA,这个问题在最初考虑是考虑到的,就是以其中两个维度做底,但是长和宽是相对的。也就是在初始构造“图”的时候,比较两个block的底时忽略了其实有两种比较方法,可以看下代码的Init中关于图构建分支条件。
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
typedef pair<int, int> base;
typedef pair<base, int> block;
const int maxn= 35;
const int maxe= maxn*3;
int n;
block a[maxe];
int eg[maxe][maxe]; // eg[i][j]== 1 => i->j is ok
int dv[maxe];
int ans;
void Init(int n)
{
memset(eg, 0, sizeof(eg));
for (int i= 0; i< n; ++i){
for (int j= i+1; j< n; ++j){
int xi= a[i].first.first, yi= a[i].first.second;
int xj= a[j].first.first, yj= a[j].first.second;
if ((xi> xj && yi > yj) || (xi> yj && yi> xj)){
eg[i][j]= 1;
}
else if ((xi< xj && yi< yj) || (xi< yj && yi< xj)){
eg[j][i]= 1;
}
}
}
memset(dv, -1, sizeof(dv));
}
int Dp(const int i)
{
if (-1!= dv[i]){
return dv[i];
}
int p= 0;
for (int j= 0; j< n; ++j){
if (eg[j][i]){
p= max(Dp(j), p);
}
}
p+= a[i].second;
dv[i]= p;
ans= max(p, ans);
return p;
}
int main(int argc, char const *argv[])
{
int kase= 0;
while (~scanf("%d", &n) && n){
int x, y, z;
ans= 0;
for (int i= 0; i< n; ++i){
scanf("%d %d %d", &x, &y, &z);
int j= 3*i;
a[j]= make_pair(make_pair(x, y), z);
a[j+1]= make_pair(make_pair(y, z), x);
a[j+2]= make_pair(make_pair(z, x), y);
}
n*= 3;
Init(n);
for (int i= 0; i< n; ++i){
Dp(i);
}
printf("Case %d: maximum height = %d\n", ++kase, ans);
}
return 0;
}