http://acm.hdu.edu.cn/showproblem.php?pid=1069
每个格子最多3个状态,也就是高最多有3种,也就是一共有N*3 最多90个格子,但是X和Y可以对调,那么就最多180个,对180个格子对X从大到小排序,X相等,Y就从大到小排序,那么这个问题就可以转换成类似求最大递减子序列问题一样思路的DP。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 30;
struct block{
int l,w,h;
}node[N*3+10];
bool cmp(const block &A, const block &B){
if(A.l != B.l) return A.l > B.l;
return A.w > B.w;
}
int dp[N*3+10],n,cnt;
///当选择一个物品会对其他物品的选择造成影响的时候,需要对物品按照某种标准排序以保证dp的正确性
int main(){
// freopen("in.txt", "r", stdin);
int t = 0;
while(scanf("%d",&n) != EOF && n){
cnt = 0;
int x,y,z;
for(int i=1; i<=n; i++){
scanf("%d%d%d",&x,&y,&z);
node[cnt].l = x, node[cnt].w = y, node[cnt++].h = z;
node[cnt].l = x, node[cnt].w = z, node[cnt++].h = y;
node[cnt].l = y, node[cnt].w = x, node[cnt++].h = z;
node[cnt].l = y, node[cnt].w = z, node[cnt++].h = x;
node[cnt].l = z, node[cnt].w = x, node[cnt++].h = y;
node[cnt].l = z, node[cnt].w = y, node[cnt++].h = x;
}
// memset(dp, 0, sizeof(dp));
sort(node, node+cnt, cmp);
for(int i=1; i<cnt; i++){
dp[i] = node[i].h;
for(int j=0; j<i; j++){
if(node[j].l > node[i].l && node[j].w > node[i].w){
dp[i] = max(dp[i], dp[j] + node[i].h);
}
}
}
int ans = 0;
for(int i=0; i<cnt; i++){
// cout << dp[i] << endl;
ans = max(ans, dp[i]);
}
printf("Case %d: ",++t);
printf("maximum height = %d\n",ans);
}
return 0;
}