题目大意:给出一系列方块,要求上面的方块长宽都比下面的小,问最高能叠多高。每个方块可以翻转,并且个数不限。
解题思路:可以翻转意味着一组长宽高能有 6 种摆放方式,列出所有方式按照长宽排序,dp记录当前方块之前能够叠的最高高度。
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<string>
#include<queue>
#include<map>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int INF = 0x3f3f3f3f;
const int NINF = -INF -1;
const int MAXN = 180+5;
using namespace std;
struct point {
int x, y, z;
};
point p[MAXN];
int dp[MAXN];
int n, ans, cnt = 0;
bool cmp(point a, point b) {
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
int main() {
while (scanf("%d", &n) && n) {
memset(dp, 0, sizeof(dp));
int t = 0;
int x, y, z;
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &x, &y, &z);
p[t].x = x, p[t].y = y, p[t].z = z, t++;
p[t].x = x, p[t].y = z, p[t].z = y, t++;
p[t].x = y, p[t].y = x, p[t].z = z, t++;
p[t].x = y, p[t].y = z, p[t].z = x, t++;
p[t].x = z, p[t].y = x, p[t].z = y, t++;
p[t].x = z, p[t].y = y, p[t].z = x, t++;
}
sort(p, p+t, cmp);
// for (int i = 0; i < t; i++)
// printf("%d %d %d\n", p[i].x, p[i].y, p[i].z);
dp[0] = p[0].z;
ans = 0;
for (int i = 1; i < t; i++) {
dp[i] = p[i].z;
for (int j = 0; j < i; j++)
if (p[j].x < p[i].x && p[j].y < p[i].y)
dp[i] = max(dp[j]+p[i].z, dp[i]);
// printf("%d %d\n", i, dp[i]);
if (dp[i] > ans) ans = dp[i];
}
printf("Case %d: maximum height = %d\n", ++cnt, ans);
}
return 0;
}