传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1069
- 思路
- 因为每个箱子的数量不限制
- 把每个立方体拆成六个位置不同的物品
- 按照 立方体的长进行排序
- 这样保证了排序后的队列是按照立方体的长 单调不减的
- 题目要求放在上面的箱子长宽要严格小于放在下面的
- 所以此时按照立方体的宽进行dp即可
if (box[k].x == box[j].x)
continue;
if (box[k].y > box[j].y) {
dp[j] = mmax(dp[k] + box[j].z, dp[j]);
}- “以宽为基准的, 以高为价值的最大价值上升序列”
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX = 33;
struct Box {
int x, y, z;
bool operator < (const Box b) {
if (x == b.x)
return y > b.y;
return x > b.x;
}
} box[6*MAX] ;
int n, x, y, z, ans, dp[6*MAX];
int mmax(int a, int b) {
return a > b ? a : b;
}
void getin() {
for (int i = 0; i < 6*n; ) {
scanf("%d%d%d", &x, &y, &z);
box[i].x = x, box[i].y = y, box[i++].z = z;
box[i].x = y, box[i].y = x, box[i++].z = z;
box[i].x = y, box[i].y = z, box[i++].z = x;
box[i].x = x, box[i].y = z, box[i++].z = y;
box[i].x = z, box[i].y = y, box[i++].z = x;
box[i].x = z, box[i].y = x, box[i++].z = y;
}
memset(dp, 0, sizeof(dp));
sort(box, box+6*n);
ans = 0;
}
int judge() {
int cnt = n*6;
for (int i = 0; i < cnt; ++i)
dp[i] = box[i].z;
for (int i = 2; i < cnt; ++i) //第当前地上有i个
for (int j = 0; j < cnt; ++j) //第i个以box[j]结尾
for (int k = 0; k < j; ++k) { //比较第 j 个与前 j-1 个
if (box[k].x == box[j].x)
continue;
if (box[k].y > box[j].y) {
dp[j] = mmax(dp[k] + box[j].z, dp[j]);
}
ans = ans > dp[j] ? ans : dp[j];
}
return ans;
}
int main() {
// freopen("in.t", "r", stdin);
// freopen("out.t", "w", stdout);
for (int T = 1; (scanf("%d", &n) == 1 && n); ++T) {
getin();
printf("Case %d: maximum height = %d\n", T, judge());
}
return 0;
}
2017-09-14