• hdu1011(树形dp)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011

    题意:有n个洞组成一棵树,你有m个士兵,你从1号房间开始攻打,每个洞有a个"bugs"和b的价值。你的一个士兵可以打20个"bugs",为了拿到这个洞的价值b你必须留下k个士兵消灭这个洞的所有"bugs"(k*20>="bugs"的数量,且留下的士兵不可以再去攻打其他的洞,且必须攻打了前面的洞才可以攻打后面的洞)。问你花费这m个士兵可以得到的最大价值是多少。 

    分析:dp[u][j]表示以u为根的子树派遣j个士兵占领的最大价值。那么每个儿子v都可以表示为价值有dp[v][k],容量为k的物品。

    所以有:dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]).

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define N 110
    #define clr(a) (memset(a,0,sizeof(a)))
    using namespace std;
    
    struct edge
    {
        int next,v;
        edge(){}
        edge(int v,int next):v(v),next(next){}
    }e[N*2];
    int dp[N][N],head[N],weight[N],cost[N],vis[N],tot,n,m;
    void addedge(int u,int v)
    {
        e[tot]=edge(v,head[u]);
        head[u]=tot++;
    }
    void dfs(int u,int fa)
    {
        vis[u]=1;
        for(int i=cost[u];i<=m;i++)dp[u][i]=weight[u];
        for(int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].v;
            if(v==fa||vis[v])continue;
            dfs(v,u);
            for(int j=m;j>=cost[u];j--)
            for(int k=1;k<=j-cost[u];k++)
            {
                dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k]);
            }
        }
    }
    int main()
    {
        int u,v;
        while(scanf("%d%d",&n,&m)>0)
        {
            if(n==-1&&m==-1)break;
            tot=0;
            memset(head,-1,sizeof(head));
            clr(dp);clr(vis);
            for(int i=1;i<=n;i++)
                scanf("%d%d",&cost[i],&weight[i]),cost[i]=(cost[i]+19)/20;
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&u,&v);
                addedge(u,v);
                addedge(v,u);
            }
            if(m==0)
            {
                puts("0");continue;
            }
           dfs(1,-1);
           printf("%d
    ",dp[1][m]);
        }
    }
    View Code
  • 相关阅读:
    jvm详解
    JVM堆外内存
    Guava基本使用
    Mondrian开源OLAP引擎详解
    Java8新特性简明教程
    TCP/IP协议三次握手和四次挥手详解
    Go 方法与函数区别
    Go 通道 Chan 详解
    kylin详细介绍
    计数排序
  • 原文地址:https://www.cnblogs.com/lienus/p/4201354.html
Copyright © 2020-2023  润新知