UVA437 巴比伦塔 The Tower of Babylon
题目链接:The Tower of Babylon - UVA 437 - Virtual Judge
题目大意:
有n种无限个长方体,每种可任意选一面作底,只有底边严格小于下方块的底边才能堆叠,求最高塔高。
拓扑:
建图时注意判断条件
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<bitset>
#include<tuple>
#include<array>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 10086, mod = 998244353;
int n, idx;
struct node {
int a, b, c;
} e[N];
void solve() {
while (cin >> n, n) {
vector<pair<int, pii>> g[4 * n];
vector<int> dis(4 * n);
for (int i = 1; i <= n; i++) {
int a, b, c;
cin >> a >> b >> c;
e[i] = {min(a, b), max(a, b), c};
e[n + i] = {min(a, c), max(a, c), b};
e[2 * n + i] = {min(b, c), max(b, c), a};
}
n *= 3;
for (int i = 1; i <= n; i++) {
auto [a1, b1, c1] = e[i];
for (int j = 1; j < i; j++) {
auto [a2, b2, c2] = e[j];
if (a1 > a2 && b1 > b2) g[i].push_back({j, {c1, c2}});
if (a1 < a2 && b1 < b2) g[j].push_back({i, {c2, c1}});
}
}
queue<int> q;
for (int i = 1; i <= n; i++) q.push(i);
int res = 0;
while (q.size()) {
int u = q.front();
q.pop();
for (auto [j, w] : g[u]) {
if (dis[j] < dis[u] + w.F) {
q.push(j);
dis[j] = max(dis[j], dis[u] + w.F);
}
res = max(res, dis[j] + w.S);
}
}
cout << "Case " << ++idx << ": maximum height = " << res << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}
DAG上dp:
类似最长上升子序列做法
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<bitset>
#include<tuple>
#include<array>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 10086, mod = 998244353;
int n, idx;
struct node {
int a, b, c;
} e[N];
void solve() {
while (cin >> n, n) {
vector<int> f(4 * n);
for (int i = 1; i <= n; i++) {
int a, b, c;
cin >> a >> b >> c;
e[i] = {min(a, b), max(a, b), c};
e[n + i] = {min(a, c), max(a, c), b};
e[2 * n + i] = {min(b, c), max(b, c), a};
}
n *= 3;
sort(e + 1, e + n + 1, [&](node x, node y) {
if (x.a == y.a) return x.b < y.b;
return x.a < y.a;
});
int res = 0;
for (int i = 1; i <= n; i++) {
auto [a1, b1, c1] = e[i];
f[i] = c1;
for (int j = 1; j < i; j++) {
auto [a2, b2, c2] = e[j];
if (a1 > a2 && b1 > b2) f[i] = max(f[i], f[j] + e[i].c);
}
res = max(res, f[i]);
}
cout << "Case " << ++idx << ": maximum height = " << res << endl;
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号