题意:
给你n种箱子的长、宽、高,他们可以一个摞另一个上面来组成一个塔,上面箱子的长宽必须严格小于下面箱子的长宽,每种箱子数量无限,问塔最高能达到多高。
思路:
最开始以为是搜索,但是算了一下状态有太多,虽然可以存是否用过边,但是思路一直比较混乱。
其实把每种箱子当成3种箱子就可以,分别有3种不同的长宽组合,那么这3种箱子的价值就是高了。
把所有的箱子长宽组合遍历出来,然后再对长宽排从小到大排序,那么此箱子能达到的最大价值就等于能摞在此箱子上的最大价值加上此箱子本身的价值。
也就是说:
f[i] 代表以i箱子为底能摞起的最大高度
那么f[i] =
∑i−1k=0f[k]
(a[k] < a[i] && b[k] < a[i])
(a[i]和b[i]分别代表长和宽)
anwser =
∑n−1i=0max(f[i])
Code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>
#define TEST
#define LL long long
#define Mt(f, x) memset(f, x, sizeof(f));
#define rep(i, s, e) for(int i = (s); i <= (e); ++i)
#ifdef TEST
#define See(a) cout << #a << " = " << a << endl;
#define See2(a, b) cout << #a << " = " << a << ' ' << #b << " = " << b << endl;
#define debug(a, s, e) rep(_i, s, e) {cout << a[_i] << ' ';} cout << endl;
#define debug2(a, s, e, ss, ee) rep(i_, s, e) {debug(a[i_], ss, ee)}
#else
#define See(a)
#define See2(a, b)
#define debug(a, s, e)
#define debug2(a, s, e, ss, ee)
#endif // TEST
const int MAX = 2e9;
const int MIN = -2e9;
const double eps = 1e-8;
const double PI = acos(-1.0);
using namespace std;
const int N = 35;
struct Node
{
int a;
int b;
int c;
Node(){}
Node(int ta, int tb, int tc)
{
a = min(ta, tb);
b = max(ta, tb);
c = tc;
}
}e[N * 3];
int n, f[N * 3];
bool cmp(Node a, Node b)
{
if(a.a != b.a)
{
return a.a < b.a;
}
return a.b < b.b;
}
int main()
{
int _ = 1;
while(~scanf("%d", &n) && n)
{
Mt(f, 0);
int a, b, c;
for(int i = 0;i < n; ++i)
{
scanf("%d%d%d", &a, &b, &c);
e[i * 3] = Node(a, b, c);
e[i * 3 + 1] = Node(a, c, b);
e[i * 3 + 2] = Node(b, c, a);
}
sort(e, e + n * 3, cmp);
int ans = MIN;
for(int i = 0; i < n * 3; ++i)
{
f[i] = e[i].c;
for(int k = 0; k < i; ++k)
{
if(e[k].a < e[i].a && e[k].b < e[i].b)
{
f[i] = max(f[i], e[i].c + f[k]);
}
}
ans = max(f[i], ans);
}
printf("Case %d: maximum height = %d\n", _++, ans);
}
return 0;
}