--- 这里是 cjiaw 的小窝(●'◡'●) ---

正在玩命加载中......

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;
}

 

posted @ 2026-02-23 22:05  wwjjw  阅读(3)  评论(0)    收藏  举报