zoukankan      html  css  js  c++  java
  • HDU 1561 The more, The Better 树形DP

    The more, The Better

    Problem Description
     
    ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?
     
    Input
     
    每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。
     
    Output
     
    对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。
     
    Sample Input
     
    3 2 0 1 0 2 0 3 7 4 2 2 0 1 0 4 2 1 7 1 7 6 2 2 0 0
     
    Sample Output
     
    5 13
     

    题意:

    题解:

      显然是有多颗树的

      对于一棵树假设根节点是x, 那么我们有size[x] 中选择这个遍历的时候DP即可

      对于所有的树,做一遍分组背包就好了

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include<vector>
    #include <algorithm>
    using namespace std;
    const int N = 2e2+20, M = 1e2+10, mod = 1e9+7, inf = 1e9+1000;
    typedef long long ll;
    
    int n,m,v[N],f[N],dp[N][N],p[N];
    vector<int > G[N];
    int siz[N];
    void dfs(int u) {
        siz[u] = 1;
        dp[u][1] = v[u];
        int totson = G[u].size();
        for(int i=0;i<G[u].size();i++) {
            int to = G[u][i];
            dfs(to);
            siz[u] += siz[to];
        }
        for(int j=0;j<totson;j++) {
            int v = G[u][j];
            for(int i=siz[u];i>=1;i--) {
                for(int k=1;k<i&&k<=siz[u];k++) {
                    dp[u][i] =  max(dp[v][k]+dp[u][i-k] , dp[u][i]);
                }
            }
        }
    }
    int main() {
        while(~scanf("%d%d",&n,&m)) {
            if(!n&&!m) break;
            int cnt = 0;
            for(int i=0;i<N;i++) G[i].clear();
            memset(dp,0,sizeof(dp));
            memset(f,0,sizeof(f));
            for(int i=1;i<=n;i++) {
                int a,b;
                scanf("%d%d",&a,&v[i]);
                if(a == 0) {p[++cnt] = i;continue;}
                G[a].push_back(i);
            }
            for(int i=1;i<=cnt;i++) dfs(p[i]);
            for(int i=1;i<=cnt;i++) {
                for(int x=m;x>=1;x--)
                for(int j=0;j<=siz[p[i]]&&j<=x;j++) {
                    f[x] = max(f[x-j] + dp[p[i]][j],f[x]);
                }
            }
            printf("%d
    ",f[m]);
    
        }
    }
  • 相关阅读:
    Tomcat gzip果然强大,js文件压缩率50%以上
    URAL 1748
    URAL 1698
    [置顶] Spring中自定义属性编辑器
    Java-类库:lombok
    专业词汇:日志(log)
    SpringBoot-application:application.yml/配置文件详解
    SpringBoot:目录
    Java-Maven-pom.xml-porject-parent:parent
    Java-Maven-pom.xml-project-packaging:packaging(war/jar)
  • 原文地址:https://www.cnblogs.com/zxhl/p/5688927.html
Copyright © 2011-2022 走看看