Description
Input
Output
Sample Input
1 10 20 30 2 6 8 10 5 5 5 7 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 5 31 41 59 26 53 58 97 93 23 84 62 64 33 83 27 0
Sample Output
Case 1: maximum height = 40 Case 2: maximum height = 21 Case 3: maximum height = 28 Case 4: maximum height = 342
贪心+动态规划
先对x,y,z进行由小到大排序得到 a[0],a[1],a[2]。每个长方体有有 (长,宽,高):(a[2],a[1],a[0]),(a[2],a[0],a[1]),(a[1],a[0],a[2])三种摆放方式
可以证明:按照规则堆砌,无论怎么样都只能三选其二 。这样与题目中长方体最多取两个不矛盾,就可以把三个摆放方式都加入到table中。
为了多的堆砌。对table按买面积由小到大进行排序。
再求table中的单调 " 递增 " 最长子序列就是解。
反过来想构造一个序列,它的单调递增子序列最长,那么贪心策略就是使它本身尽可能的满足单调递增。
#include <stdio.h> #include <vector> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAX_SIZE 10000 #define find_max(a,b) a>b?a:b; using namespace std; struct node{ int l,w,h; bool operator < (const node &p) const{ return l*w<p.l*p.w; } bool operator >(const node &p) const{ return (l>p.l)&&(w>p.w); } }; vector<node> ln; int dp[3*MAX_SIZE]; int main() { int n; int count=1; while(~scanf("%d",&n)) { if(n==0) break; ln.clear(); int a[3]; for(int i=0;i<n;++i) { scanf("%d%d%d",a,a+1,a+2); sort(a,a+3); ln.push_back((node){a[2],a[1],a[0]}); ln.push_back((node){a[2],a[0],a[1]}); ln.push_back((node){a[1],a[0],a[2]}); } sort(ln.begin(),ln.end()); dp[0]=ln[0].h; int ans=ln[0].h; for(int i=1;i<ln.size();++i) { dp[i]=ln[i].h; for(int j=i-1;j>=0;--j) if(ln[i]>ln[j]) dp[i]=find_max(dp[i],dp[j]+ln[i].h); ans=find_max(ans,dp[i]); } printf("Case %d: maximum height = %d\n",count,ans); ++count; } return 0; }