解析:将每种立方体的各种摆放形式均视为不同的立方体,并存起来。再将所有立方体按照下底面的面积从小到大排序(因为在塔上面的立方体的底面积一定比下面的小),然后求该序列的最大上升子序列的高度。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 35 * 3; struct Node { int x,y,z; }box[N]; int dp[N]; bool cmp(Node a,Node b) { if(a.x != b.x) { return a.x < b.x; }else { return b.y < b.y; } } int main() { int n,cas = 1; int l[3]; while(scanf("%d",&n) != EOF && n) { for(int i = 0; i < n*3; i += 3) { scanf("%d%d%d",&l[0],&l[1],&l[2]); sort(l,l+3); box[i].x = l[0]; box[i].y = l[1]; box[i].z = l[2]; box[i+1].x = l[0]; box[i+1].y = l[2]; box[i+1].z = l[1]; box[i+2].x = l[1]; box[i+2].y = l[2]; box[i+2].z = l[0]; } int maxx = 0; sort(box,box+n*3,cmp); memset(dp,0,sizeof(dp)); for(int i = 0; i < n*3; i++) { dp[i] = box[i].z; for(int j = 0; j <= i; j++) { if(box[i].x > box[j].x && box[i].y > box[j].y) { dp[i] = max(dp[i],dp[j] + box[i].z); } } if(dp[i] > maxx) { maxx = dp[i]; } } printf("Case %d: maximum height = %d\n",cas++,maxx); } return 0; }