UVa 437 - The Tower of Babylon
传送门
UVa 437 - The Tower of Babylon
题意
给出几个三维的矩形,每种数量不限。底面严格递增可以叠起来,求最长高。矩形三维可以随便换。
思路
因为只要比较底面,所以可以把一个矩形xyz变成xyz,xzy,yzx三种,每种的底面都不一样。然后和以前的矩形嵌套一样了。
代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 200;
struct RECTAN
{
int x, y, z;
};
int n, dp[MAXN], mp[MAXN][MAXN];
vector<RECTAN> ve;
void Input()
{
RECTAN temp;
int i;
for (i = 0; i < n; i++)
{
scanf("%d%d%d", &temp.x, &temp.y, &temp.z);
ve.push_back(temp);
swap(temp.y, temp.z);
ve.push_back(temp);
swap(temp.x, temp.z);
ve.push_back(temp);
}
}
bool isBigger(RECTAN a, RECTAN b)
{
if (a.x > a.y)
swap(a.x, a.y);
if (b.x > b.y)
swap(b.x, b.y);
if (a.x < b.x && a.y < b.y)
return true;
return false;
}
int DFS(int i)
{
int &ans = dp[i];
if (ans != -1)
return ans;
ans = 0;
for (int j = 0; j < ve.size(); j++)
if (mp[i][j])
ans = max(ans, DFS(j));
ans += ve[i].z;
return ans;
}
int main()
{
//freopen("in.txt", "r", stdin);
int i, j, a, b, c, ans, cases = 1;
while (scanf("%d", &n), n)
{
memset(dp, -1, sizeof(dp));
memset(mp, 0, sizeof(mp));
ans = -1;
ve.clear();
Input();
for (i = 0; i < ve.size(); i++)
for (j = 0; j < ve.size(); j++)
if (isBigger(ve[i], ve[j]))
mp[i][j] = 1;
for (i = 0; i < ve.size(); i++)
ans = max(ans, DFS(i));
printf("Case %d: maximum height = %d\n", cases++, ans);
}
return 0;
}