这道题是典型的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 }