• HDU 1561:The more, The Better(有依赖的树型背包)


    http://acm.hdu.edu.cn/showproblem.php?pid=1561

    题意:有n个点,容量为m,每个点有一个价值,还给出n条边,代表选第i个点之前必须先选ai,问最多的价值能取多少。

    思路:每个点的花费是1,价值为w[i],然后直接按照树型背包写就行了。

    还是老套路。

    dp[i][j] 表示以 i 为根结点的子树最大价值,然后像01背包一样枚举容量,再用一层循环去给子结点分配容量,最后回溯到根节点,根节点的值就是答案了。

    因为是森林,所以添加一个0结点当作根,记得0结点是没有花费也没有价值的。

    感觉写的不是很严谨,直接认为是一棵树了,没考虑缩点。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define N 205
     4 struct Edge {
     5     int v, nxt;
     6 } edge[N];
     7 int head[N], tot, w[N], c[N], n, m, dp[N][N], deg[N];
     8 
     9 void Add(int u, int v) { edge[tot] = (Edge) {v, head[u]}; head[u] = tot++; }
    10 
    11 void dfs(int u) {
    12     for(int j = m; j >= c[u]; j--) dp[u][j] = w[u]; // 赋予初值,因为必须选第u个点,才能去更新子结点
    13     for(int i = head[u]; ~i; i = edge[i].nxt) {
    14         int v = edge[i].v;
    15         dfs(v);
    16         for(int j = m; j >= c[u]; j--) {
    17             for(int k = 0; k <= j - c[u]; k++) { // 枚举分配给子结点的容量
    18                 dp[u][j] = max(dp[u][j], dp[u][j-k] + dp[v][k]);
    19             }
    20         }
    21     }
    22 }
    23 
    24 void solve() {
    25     for(int i = 1; i <= n; i++) c[i] = 1;
    26     memset(dp, 0, sizeof(dp));
    27     memset(deg, 0, sizeof(deg));
    28     memset(head, -1, sizeof(head));
    29     tot = 0;
    30     for(int i = 1; i <= n; i++) {
    31         int a; scanf("%d%d", &a, &w[i]);
    32         if(a == 0) continue;
    33         Add(a, i); deg[i]++;
    34     }
    35     for(int i = 1; i <= n; i++) if(!deg[i]) Add(0, i);
    36     dfs(0);
    37     printf("%d
    ", dp[0][m]);
    38 }
    39 
    40 int main() {
    41     while(scanf("%d%d", &n, &m), n + m) solve();
    42     return 0;
    43 }
  • 相关阅读:
    Android学习进程 Java引用 Rxjava MVP
    小试 Xcode 逆向:App 内存监控原理初探
    春招路上孤独的iOSer的心路历程(面经)
    【译】4个你需要知道的Asset Catalog的秘密
    超全!iOS 面试题汇总
    整理 iOS 9 适配中出现的坑(图文)
    旧版Xcode下载地址
    xcode 自动添加注释,生成文档
    NDK_ROOT找不到的解决方法 MACOS
    13个小技巧帮你征服Xcode
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6522755.html
Copyright © 2020-2023  润新知