题目大意:给出n个方块,每个方块的长宽高。每个方块有任意多块,叠的要求下一方块的长宽都比上一方块长。问最多能叠多高。
解题思路:每个方块放在地面有三种方式,根据长宽的不同(长大于等于宽)。根据题最多叠的方式不过每个方块用三次,也就是每种方式用一次。对所有摆放方式的方块根据长、宽排序,这样每次能确保上面的长或宽较小,才有叠放的可能性。dp初始为每个方块的高。每个方块都判断其下面能放的高度。
ac代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node{int lenth;int width;int high;
}block[100];
bool compare(node a, node b)
{if (a.lenth != b.lenth)return a.lenth > b.lenth;return a.width > b.width;
}
int main()
{int n, Max, dp[100], a[3], cnt, num=1;while (scanf("%d", &n)!=EOF && n){cnt = 0;for (int i=0; i<n; i++){scanf("%d%d%d", &a[0], &a[1], &a[2]);sort(a, a+3);block[cnt].lenth = a[0];block[cnt].width = a[1];block[cnt++].high = a[2]; block[cnt].lenth = a[1];block[cnt].width = a[2];block[cnt++].high = a[0];block[cnt].lenth = a[0];block[cnt].width = a[2];block[cnt++].high = a[1]; } sort(block, block+cnt, compare);for (int i=0; i<cnt; i++)dp[i] = block[i].high;for (int i=1; i<cnt; i++)for (int j=0; j<i; j++){if (block[i].lenth < block[j].lenth && block[i].width < block[j].width)dp[i] = max(dp[i], dp[j]+block[i].high); } Max = dp[0];for (int i=1; i<cnt; i++)Max = max(Max, dp[i]); printf("Case %d: maximum height = %d\n", num++, Max);}
return 0;
}