题意:见紫书
题解:
一道水得不能再水的大水题,却让我给想多了
每种立方体的长宽高有6种不同的情况,把输入的拆成6个来考虑
用最长上升子序列的思维,状态转移方程 dp[i]=max(dp[i],dp[j]+p[i].h);
因为开始时立方体是无序的,所以按长或者宽或者什么神奇的东西拍个序
使能够让第i个立方体堆上的所有合法方案一定都在前i-1个立方体里面就可以
啊啊啊,我竟然没想出来,看了题解后简直想捶自己。。。
code:
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
const int MAXN=185;
using namespace std;
struct node{int a,b,c;}p[MAXN];
int cas,n,a,b,c,dp[MAXN];
bool cmp(node t1,node t2){
return t1.a>t2.a;
}
int main()
{
while(scanf("%d",&n),n)
{
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&a,&b,&c);
p[i] = (node){a,b,c};
p[n+i]=(node){a,c,b};
p[n*2+i]=(node){b,a,c};
p[n*3+i]=(node){b,c,a};
p[n*4+i]=(node){c,a,b};
p[n*5+i]=(node){c,b,a};
}
n*=6; int ans=0;
sort(p+1,p+n+1,cmp);
for(int i=1;i<=n;i++)
{
dp[i]=p[i].c;
for(int j=1;j<i;j++)
if(p[i].a<p[j].a&&p[i].b<p[j].b)
dp[i]=max(dp[i],dp[j]+p[i].c);
ans=max(ans,dp[i]);
}
printf("Case %d: maximum height = %d\n",++cas,ans);
}
}