hdu-acm steps Monkey and Banana

这道题是典型的dp题。首先是数据的处理上,因为每个长方体的3条不同长度的棱都可以作为高,因此一个长方体可以看成3个不同的长方体。从而将数据扩展为3*n,然后将所有的长方体以长度为第一排序条件,宽度为第二排序条件进行排序。接着整个问题就变成了求最长递减子序列的问题了,多得到的状态方程为:dp[i]=max{dp[i],dp[j]+blocks[i].z}.其中dp[i]是以第i块木块为最顶上的木块时多得到的最大高度,即最优子结构。最后找到最最优的子结构即为本题的最大高度。

 1 #include"iostream"
 2 #include"stdio.h"
 3 #include"algorithm"
 4 #include"string.h"
 5 #include"cmath"
 6 #include"queue"
 7 #define mx 1005
 8 using namespace std;
 9 struct node
10 {
11     int x,y,z;
12 }blocks[mx];
13 int n,dp[mx];
14 bool cmp(const node a,const node b) //以长为第一要求,宽为第二要求进行排序
15 {
16     if(a.y!=b.y) return a.y>b.y;
17     else return a.x>b.x;
18 }
19 int main()
20 {
21     int count1=0;
22     while(cin>>n,n)
23     {
24         count1++;
25         int i,j,k;
26         for(j=0,i=0;i<n;i++) //将一个木块变成3个
27           {
28               int a,b,c;
29               cin>>a>>b>>c;
30               blocks[j].x=min(a,b);
31               blocks[j].y=max(a,b);
32               blocks[j++].z=c;
33               blocks[j].x=min(a,c);
34               blocks[j].y=max(a,c);
35               blocks[j++].z=b;
36               blocks[j].x=min(b,c);
37               blocks[j].y=max(b,c);
38               blocks[j++].z=a;
39           }
40           k=j;
41           sort(blocks,blocks+k,cmp);//排序
42           int maxhigh=0;//记录最长上升子序列的长度
43           for(i=0;i<k;i++)
44           {
45               dp[i]=blocks[i].z;//对dp[]进行初始化
46               for(j=0;j<i;j++)
47               {
48                   if(blocks[j].x>blocks[i].x&&blocks[j].y>blocks[i].y&&dp[j]+blocks[i].z>dp[i])//判断条件缺一不可
49                   {
50                       dp[i]=dp[j]+blocks[i].z;
51                   }
52               }
53               if(dp[i]>maxhigh) maxhigh=dp[i];
54           }
55           cout<<"Case "<<count1<<": maximum height = "<<maxhigh<<endl;
56     }
57     return 0;
58 }
View Code
原文地址:https://www.cnblogs.com/acm-jing/p/4252057.html