题意: 给你n种立方体的长宽高,每种都有无限个,立方体可以旋转。现在要摞立方体使得摞起来的高度尽可能高,要求上面的立方体的长和宽必须严格小于下面的立方体。
思路:每种立方体都有三种摆法,长宽高:(a, b, c)(a, c, b) (b, c, a) 输入的时候处理一下,存n*3个立方体。可以排一下序LIS来做,也可以记忆化搜索。
我写的记忆化搜索,但是一直WA,后来改成了LIS,可还是WA,看了半天也没看出有什么bug,于是去看了别人写的,发现跟我写的本质上没什么区别。。。。。。
最后发现不是我写错了,而是。。。用G++交可以过,之前一直用C++交就会WA,WTF,什么鬼。。。
记忆化搜索:
# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 100 + 5;
int dp[maxn];
int G[maxn][maxn];
int n;
struct Node {
int a, b, c;
void Set(int aa, int bb, int cc) {
a = aa; b = bb; c = cc;
}
} res[maxn];
int dfs(int);
void init();
int main(void)
{
int Case = 0;
while (scanf("%d", &n) && n) {
init();
int ans = 0;
for (int i = 0; i < n; ++i) ans = max(ans, dfs(i));
printf("Case %d: maximum height = %d\n", ++Case, ans);
}
return 0;
}
int dfs(int id) {
int& d = dp[id];
if (d != -1) return d;
d = res[id].c;
for (int i = 0; i < n; ++i) {
if (G[id][i]) d = max(d, dfs(i) + res[id].c);
}
return d;
}
void init() {
memset(dp, -1, sizeof dp);
memset(G, 0, sizeof G);
int t = 0; n *= 3;
while (t < n) {
scanf("%d %d %d", &res[t].a, &res[t].b, &res[t].c); ++t;
res[t++].Set(res[t - 1].a, res[t - 1].c, res[t - 1].b);
res[t++].Set(res[t - 1].b, res[t - 1].c, res[t - 1].a);
}
for (int i = 0; i < n; ++i) {
if (res[i].a < res[i].b) swap(res[i].a, res[i].b);
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (res[i].a < res[j].a && res[i].b < res[j].b)
G[i][j] = 1;
}
}
}
LIS:
# include <iostream>
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 100 + 5;
int dp[maxn];
int n;
struct Node {
int a, b, c;
bool operator < (const Node& n) const {
if (a == n.a) return b > n.b;
return a > n.a;
}
void Set(int aa, int bb, int cc) {
a = aa; b = bb; c = cc;
}
} res[maxn];
int main(void)
{
int Case = 0;
while (scanf("%d", &n) && n) {
int t = 0; n *= 3;
while (t < n) {
scanf("%d %d %d", &res[t].a, &res[t].b, &res[t].c); ++t;
res[t++].Set(res[t - 1].a, res[t - 1].c, res[t - 1].b);
res[t++].Set(res[t - 1].b, res[t - 1].c, res[t - 1].a);
}
for (int i = 0; i < n; ++i) {
if (res[i].a < res[i].b) swap(res[i].a, res[i].b);
}
sort(res, res + n);
for (int i = 0; i < n; ++i) dp[i] = res[i].c;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (res[i].a < res[j].a && res[i].b < res[j].b)
dp[i] = max(dp[i], dp[j] + res[i].c);
}
}
int ans = 0;
for (int i = 0; i < n; ++i) ans = max(ans, dp[i]);
printf("Case %d: maximum height = %d\n", ++Case, ans);
}
return 0;
}