zoukankan      html  css  js  c++  java
  • hdu1561 The more, The Better (树形DP)

    The more, The Better

    Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 9938    Accepted Submission(s): 5788


    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
     
    Author
    8600
     
     
    树形DP模板题。
    其实就是一个分组背包。
     
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define lol long long
    #define maxn 200
    
    using namespace std;
    
    int n,m;
    int to[maxn+5];
    int nex[maxn+5];
    int head[maxn+5];
    int cnt;
    
    void addedge(int u,int v)
    {
        to[cnt]=v;
        nex[cnt]=head[u];
        head[u]=cnt++;
    }
    
    int val[maxn+5];
    
    int dp[maxn+5][maxn+5];
    
    void dfs(int x)
    {
        for(int i=1;i<=m;i++)
            dp[x][i]=val[x];
        for(int i=head[x];i!=-1;i=nex[i])
        {
            dfs(to[i]);
            //分组背包
            for(int j=m;j>1;j--)//--保证每组只用一个
                for(int k=1;k<j;k++)
                    dp[x][j]=max(dp[x][j],dp[x][j-k]+dp[to[i]][k]);
        }
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m),n||m)
        {
            memset(head,-1,sizeof(head));
            memset(val,0,sizeof(head));
            cnt=0;
            for(int i=1,a,b;i<=n;i++)
            {
                scanf("%d%d",&a,&b);
                addedge(a,i);
                val[i]=b;
            }
    
            m++;
            memset(dp,0,sizeof(dp));
            dfs(0);
    
            printf("%d
    ",dp[0][m]);
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    Leetcode Spiral Matrix
    Leetcode Sqrt(x)
    Leetcode Pow(x,n)
    Leetcode Rotate Image
    Leetcode Multiply Strings
    Leetcode Length of Last Word
    Topcoder SRM 626 DIV2 SumOfPower
    Topcoder SRM 626 DIV2 FixedDiceGameDiv2
    Leetcode Largest Rectangle in Histogram
    Leetcode Set Matrix Zeroes
  • 原文地址:https://www.cnblogs.com/acboyty/p/9826732.html
Copyright © 2011-2022 走看看