/*
translation:
给出n种类型的箱子,每种箱子数量可以无限供应。当一个箱子的底面长宽严格比另一个箱子要小时才可以重叠在上面。
问最高可以叠多高?
solution:
记忆化搜索即可
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 100;
struct Box
{
int x, y, z;
Box(int x_, int y_, int z_):x(x_), y(y_), z(z_) {}
Box() {}
};
int n, d[maxn];
vector<int> stackble[maxn]; //stackble[i]里面保存的全都是能够堆叠在i号箱子底下的箱子编号
vector<Box> boxVec;
int inline max(const int &a, const int &b)
{
return a > b ? a : b;
}
int dp(int x)
{
if(d[x] > 0) return d[x];
int res = boxVec[x].z;
for(int i = 0; i < stackble[x].size(); i++) {
int nextid = stackble[x][i];
res = max(res, dp(nextid) + boxVec[x].z);
}
return d[x] = res;
}
bool inline check(const Box& a, const Box& b)
{
int xa = a.x, ya = a.y; if(xa > ya) swap(xa, ya);
int xb = b.x, yb = b.y; if(xb > yb) swap(xb, yb);
if(xa < xb && ya < yb) return true;
else return false;
}
int main()
{
//freopen("in.txt", "r", stdin);
int kase = 0;
while(~scanf("%d", &n) && n) {
for(int i = 0; i < maxn; i++) stackble[i].clear();
boxVec.clear();
memset(d, 0, sizeof(d));
int x, y, z;
for(int i = 0; i < n; i++) {
scanf("%d%d%d", &x, &y, &z);
boxVec.push_back(Box(x, y, z));
boxVec.push_back(Box(x, z, y));
boxVec.push_back(Box(y, z, x));
}
for(int i = 0; i < boxVec.size(); i++) {
for(int j = 0; j < boxVec.size(); j++) if(i != j) {
if(check(boxVec[i], boxVec[j]))
stackble[i].push_back(j);
}
}
/*
for(int i = 0; i < boxVec.size(); i++) {
printf("%d %d %d:->\n", boxVec[i].x, boxVec[i].y, boxVec[i].z);
for(int j = 0; j < stackble[i].size(); j++) {
int k = stackble[i][j];
printf("%d %d %d\n", boxVec[k].x, boxVec[k].y, boxVec[k].z);
}
}
*/
int ans = 0;
for(int i = 0; i < boxVec.size(); i++) {
ans = max(ans, dp(i));
}
printf("Case %d: maximum height = %d\n", ++kase, ans);
}
return 0;
}
hdu1069(*记忆化搜索)
最新推荐文章于 2019-07-08 20:39:52 发布