The Tower of Babylon UVA - 437 DAG上的动态规划

时间:2023-03-10 04:23:07
The Tower of Babylon UVA - 437 DAG上的动态规划

题目:题目链接

思路:每个方块可以用任意多次,但因为底面限制,每个方块每个放置方式选一个就够了,以x y为底 z 为高,以x z为底 y 为高,以y z为底 x为高,因为数据量很小,完全可以把每一种当成DAG上的一个结点,然后建图找最长路径。

AC代码:

 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <list> #define FRER() freopen("in.txt", "r", stdin)
#define FREW() freopen("out.txt", "w", stdout) #define INF 0x3f3f3f3f using namespace std; struct block {
int x, y, z;
block() {}
block(int x, int y, int z):x(x), y(y), z(z) {}
bool operator < (const block & other) const {
return (x < other.x && y < other.y) || (x < other.y && y < other.x);
}
}; vector<block> vec; int n, m, d[];
bool G[][]; void init() {
vec.clear();
int x, y, z;
for(int i = ; i < n; ++i) {
cin >> x >> y >> z;
vec.push_back(block(x, y, z));
vec.push_back(block(x, z, y));
vec.push_back(block(y, z, x));
}
m = n * ;
memset(G, , sizeof(G));
for(int i = ; i < m; ++i)
for(int j = ; j < m; ++j)
if(vec[i] < vec[j])
G[i][j] = ; memset(d, , sizeof(d));
} int dp(int i, int h) {
if(d[i]) return d[i];
int& ans = d[i];
ans = h;
m = n * ;
for(int j = ; j < m; ++j) {
if(G[i][j])
ans = max(ans, dp(j, vec[j].z) + h);
}
return ans;
} int solve() {
int ans = -;
for(int i = ; i < m; ++i)
ans = max(ans, dp(i, vec[i].z));
return ans;
} int main()
{
//FRER();
//FREW();
ios::sync_with_stdio();
cin.tie(); int kase = ;
while(cin >> n, n) {
init();
cout << "Case " << ++kase << ": maximum height = " << solve() << endl;
} return ;
}