Uva 437 - The Tower of Babylon(DP)

题目链接 https://vjudge.net/problem/UVA-437

【题意】
       给定n种不同的立方体,每种立方体都有无穷多个,现在要用它们跌放在一起组成一个巴比伦塔,并且处在某个位置的立方体的底面长和宽一定严格小于它下面的那个立方体,你的任务是求出可以搭成的最高的塔高是多少?

【思路】
       把底面的长和宽以及对应的高当成一个状态结点,然后如果结点i能叠放在结点j之上那么就连接一条i到j的有向边,这样就形成了一个DAG,然后用动态规划求解带权值的最长路即可.

#include<bits/stdc++.h>
using namespace std;

const int maxn = 35 * 3;

int n, cnt;
vector<int> g[maxn];
int dp[maxn];

struct Node {
    int r, c;
    int h;
    Node(int rr = 0, int cc = 0, int hh = 0) : r(rr), c(cc), h(hh) {}
}node[maxn];

int dfs(int u) {
    if (g[u].size() == 0) {
        return dp[u] = node[u].h;
    }
    if (dp[u] != -1) return dp[u];
    int ans = 0;
    for (int i = 0; i < g[u].size(); ++i) {
        int v = g[u][i];
        ans = max(ans, node[u].h + dfs(v));
    }
    return dp[u] = ans;
}

int main() {
    int kase = 0;
    while (scanf("%d", &n) == 1 && n) {
        cnt = 0;
        for (int i = 0; i < n; ++i) {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            node[cnt++] = Node(a, b, c);
            node[cnt++] = Node(a, c, b);
            node[cnt++] = Node(b, c, a);
        }
        for (int i = 0; i < cnt; ++i) g[i].clear();
        for (int i = 0; i < cnt; ++i) {
            for (int j = 0; j < cnt; ++j) {
                if (i == j) continue;
                if ((node[i].r < node[j].r && node[i].c < node[j].c) || (node[i].r < node[j].c && node[i].c < node[j].r)) {
                    g[i].push_back(j);//底面小的指向底面大的
                }
            }
        }
        memset(dp, -1, sizeof(dp));
        for (int i = 0; i < cnt; ++i) {
            if (-1 == dp[i]) dfs(i);
        }
        int ans = 0;
        for (int i = 0; i < cnt; ++i) {
            ans = max(ans, dp[i]);
        }
        printf("Case %d: maximum height = %d\n", ++kase, ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值