题目:monkey想吃banana,但是banana挂在一定的高度,现在有长宽高为,x,y,h的长方体,要你堆成一个台阶让monkey可以踩在上面,要求,上一层的 地面长和宽都要小于下层的,这样monkey在上台阶时才可以方便
分析:因为每个长方体都有无数个可以使用,故先对输入的x,y,h排序成t1,t2,t3,(t1<=t2<=t3)再把一个长方体拆成三个长宽高分别为,t3,t2,t1; t3,t1,t2; t2,t1,t3;
先按长排序,再按宽二级排序,对宽进行类似最长上升子序列,的dp,状态转移方程:
dp[i]=max(dp[j])+h;(1<=j<i)......
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; struct node { int x,y,h; }arr[1000]; int dp[1000]; int cmp(node x,node y) { if(x.x==y.x) return x.y<y.y;//升序 else return x.x<=y.x; } int main() { int n,t=1; while(scanf("%d",&n)!=EOF) { if(n==0) break; int x,y,h,c=1; for(int i=1;i<=n;i++) { scanf("%d %d %d",&x,&y,&h); int t1=max(max(x,y),h); int t2=min(min(x,y),h); int t3=x+y+h-t1-t2;//t2<=t3<=t1 arr[c].x=t2; arr[c].y=t3; arr[c++].h=t1; arr[c].x=t3; arr[c].y=t1; arr[c++].h=t2; arr[c].x=t2; arr[c].y=t1; arr[c++].h=t3; } //dp[1]=arr[1].h;放错位置了 sort(arr+1,arr+1+3*n,cmp); dp[1]=arr[1].h; for(int i=2;i<c;i++) { /* int low=1,high=i-1,mid; while(low<=high) { mid=(low+high)/2; if(arr[i].x<dp[mid].x&&arr[i].y<dp[mid].y) high=mid-1; else if(dp[mid].x<arr[i].x&&dp[mid].y<arr[i].y) high=mid+1; }*/ int ans=0; for(int j=1;j<i;j++) { if(arr[i].x!=arr[j].x && arr[i].y>arr[j].y&&dp[j]>ans) { ans=dp[j]; } } dp[i]=ans+arr[i].h; } /*for(int i=1;i<c;i++) printf("%d**** \n",dp[i]); printf("\n");*/ int ans=0; for(int i=1;i<c;i++) if(dp[i]>ans) ans=dp[i]; printf("Case %d: maximum height = %d\n",t++,ans); } system("pause"); return 0; }