题目大意:给出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;
}