题目大意:给你N种积木,每种的数量不限,现在要求你求出能用这些积木堆出的最大高度
堆的规则如下:在底下的积木的的长和宽要大于在其上面的所有积木的长和宽
解题思路:一种积木有6种摆放方式,所以先预处理出每种积木的所有摆放方式
因为长宽限制,所以每种积木的每种摆放方式最多只有一块
接着排个序,按照面积排序,接下来就是纯DAG问题了
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 210;
struct Block{
int x, y, z;
}B[N];
int dp[N];
int n;
bool cmp(const Block &a, const Block &b) {
return a.x * a.y > b.x * b.y;
}
void init() {
//1 2 3
for (int i = 0; i < n; i++)
scanf("%d%d%d", &B[i].x, &B[i].y, &B[i].z);
int cnt = n;
for (int i = 0; i < n; i++) {
B[cnt].x = B[i].x; B[cnt].y = B[i].z; B[cnt++].z = B[i].y; //1 3 2
B[cnt].x = B[i].y; B[cnt].y = B[i].x; B[cnt++].z = B[i].z; //2 1 3
B[cnt].x = B[i].y; B[cnt].y = B[i].z; B[cnt++].z = B[i].x; //2 3 1
B[cnt].x = B[i].z; B[cnt].y = B[i].x; B[cnt++].z = B[i].y; //3 1 2
B[cnt].x = B[i].z; B[cnt].y = B[i].y; B[cnt++].z = B[i].x; //3 2 1
}
n = cnt;
}
int cas = 1;
void solve() {
sort(B, B + n, cmp);
for (int i = 0; i < n; i++)
dp[i] = B[i].z;
for (int i = 0; i < n; i++)
for (int j = 0; j < i; j++)
if (B[i].x < B[j].x && B[i].y < B[j].y)
dp[i] = max(dp[i], dp[j] + B[i].z);
int ans = 0;
for (int i = 0; i < n; i++)
ans = max(ans, dp[i]);
printf("Case %d: maximum height = %d\n", cas++, ans);
}
int main() {
while (scanf("%d", &n) != EOF && n) {
init();
solve();
}
return 0;
}