zoukankan      html  css  js  c++  java
  • HDU1561:The more, The Better(树形DP+01背包)

    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


     

    题意就不多解释了,毕竟中文题

    思路我也是参考的别人的代码,因为这道题结合了01背包的思想,一开始没有想到

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    
    struct node
    {
        int from,to,next;
    } tree[205];
    
    int vis[205],dp[205][205],ans[205][205],head[205],mat[205];
    int len,n,m;
    
    void add(int a,int b)
    {
        tree[len].from = a;
        tree[len].to = b;
        tree[len].next = head[a];
        head[a] = len++;
    }
    
    void dfs(int root)
    {
        int i,j,k,tem;
        vis[root] = 1;
        for(i = head[root]; i!=-1; i = tree[i].next)
        {
            tem = tree[i].to;
            if(!vis[tem])
            {
                dfs(tem);
                for(k = m; k>=0; k--)//01背包
                {
                    for(j = 0; j<=k; j++)
                        ans[root][k] = max(ans[root][k],ans[root][k-j]+dp[tem][j]);
                }
            }
        }
        for(j = 1; j<=m+1; j++)
            dp[root][j] = ans[root][j-1]+mat[root];
    }
    
    int main()
    {
        int i,a,b;
        while(~scanf("%d%d",&n,&m),n+m)
        {
            len = 0;
            memset(head,-1,sizeof(head));
            for(i = 1; i<=n; i++)
            {
                scanf("%d%d",&a,&b);
                mat[i] = b;
                add(a,i);
            }
            mat[0] = 0;
            memset(vis,0,sizeof(vis));
            memset(dp,0,sizeof(dp));
            memset(ans,0,sizeof(ans));
            dfs(0);
            printf("%d
    ",dp[0][m+1]);
        }
    
        return 0;
    }
    


     

  • 相关阅读:
    概率期望,数学,贪心策略——2020-camp-day1-A
    k染色——2020-camp-day3-C
    树形dp——2020-camp-day3-G
    欧拉回路/路径——2020-camp-day2-H
    dsu on tree——2020-camp-day2-E
    Nim博弈,异或性质——2020-camp-day2-C
    一些视频资料
    开发人员收藏的网站
    各行公认的好书
    资料库链接
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3249393.html
Copyright © 2011-2022 走看看