状态转移方程: dp[i]=max(dp[j]+a[i].z,dp[i]);
既然每个石头有三种方法,那么就看成3个石头,先按长宽排序,在做dp就行了。
/********************** * author:crazy_石头 * Pro:HDOJ 1069 * algorithm:dp * Time:0ms * Judge Status:Accepted ***********************/ #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define INF 0xfffffff using namespace std; const int maxn=1005; long long dp[maxn*3]; int n,ans; struct cube { int x,y,z; }a[maxn*3+5]; inline long long max(long long a,long long b) { return a>b?a:b; } inline long long min(long long a,long long b) { return a<b?a:b; } bool cmp(cube a,cube b) { if (a.x == b.x) return a.y>b.y; else return a.x>b.x; } int main() { int t=1; while(scanf("%d",&n)!=EOF&&n) { int x,y,z; for(int i=1;i<=n;i++) { scanf("%d%d%d",&x,&y,&z); a[i].x=max(x,y),a[i].y=min(x,y),a[i].z=z; a[i+n].x=max(x,z),a[i+n].y=min(x,z),a[i+n].z=y; a[i+2*n].x=max(y,z),a[i+2*n].y=min(y,z),a[i+2*n].z=x; } sort(a+1,a+3*n+1,cmp); memset(dp,0,sizeof(dp)); a[0].x=INF; a[0].y=INF; a[0].z=INF; ans=0; for(int i=1;i<=3*n;i++) { for(int j=0;j<i;j++) { if (a[j].x>a[i].x &&a[j].y>a[i].y) dp[i]= max(dp[i],dp[j]+a[i].z); } ans=max(ans,dp[i]); } printf("Case %d: ",t++); cout<<"maximum height = "<<ans<<endl; } return 0; } |
* This source code was highlighted byYcdoiT. ( style: Zenbum )