题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1069
分析: 每种石头有六种方法,那么等效为:有6*n种石头。
根据x和y排序(要保证相应的x、y总有x>=y),然后dp[i]=
max{s[i].z,s[i].z+dp[j]}(j<i,且石块i放于石块j上,符合题意)。
其实就是最长上升子序列的换种求法。。。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#define LL long long
using namespace std;
int dp[];
struct node
{
int x,y,z;
}s[];
int cmp(node a,node b)
{
if(a.x!=b.x)return a.x>b.x;
else if(a.y!=b.y)return a.y>b.y;
else return a.z>b.z;
}
int main()
{
int n,cas=;
while(scanf("%d",&n)&&n)
{
int tot=;
for(int i=;i<=n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
s[tot].x=x;s[tot].y=y;s[tot].z=z;
tot++;
s[tot].x=x;s[tot].y=z;s[tot].z=y;
tot++;
s[tot].x=y;s[tot].y=x;s[tot].z=z;
tot++;
s[tot].x=y;s[tot].y=z;s[tot].z=x;
tot++;
s[tot].x=z;s[tot].y=y;s[tot].z=x;
tot++;
s[tot].x=z;s[tot].y=x;s[tot].z=y;
tot++;
}
sort(s+,s+tot,cmp);
memset(dp,,sizeof(dp));
dp[]=s[].z;
int ans=-;
for(int i=;i<tot;i++)
{//printf("%d %d %d\n",s[i].x,s[i].y,s[i].z);
int mx=;
for(int j=;j<i;j++)
if(s[j].x>s[i].x&&s[j].y>s[i].y&&dp[j]+s[i].z>mx)mx=dp[j]+s[i].z;
if(mx==)dp[i]=s[i].z;
else
dp[i]=mx;
ans=max(mx,ans);
}
printf("Case %d: maximum height = %d\n",cas++,ans);
}
}