题目链接: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[200]; struct node { int x,y,z; }s[200]; 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=1; while(scanf("%d",&n)&&n) { int tot=1; for(int i=1;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+1,s+tot,cmp); memset(dp,0,sizeof(dp)); dp[1]=s[1].z; int ans=-1; for(int i=2;i<tot;i++) {//printf("%d %d %d ",s[i].x,s[i].y,s[i].z); int mx=0; for(int j=1;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==0)dp[i]=s[i].z; else dp[i]=mx; ans=max(mx,ans); } printf("Case %d: maximum height = %d ",cas++,ans); } }