• HDU 1011 (树形DP+背包)


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

    题目大意:树上取点,先取父亲,再取儿子。每个点,权为w,花费为cost,给定m消费总额,求最大权和。

    解题思路

    树形背包模板题。首先建一个无向图。

    每个点的cost=(bug[root]+19)/20,即虫子数不满20也要派一个人。

    用dp[i][j]表示以i为根的子树中,花费为j的最大权和。

    转移方程:dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[t][k]),其中t为儿子之一,k为分配给儿子的cost。

    采用dfs对每个root进行DP。

    每次dfs的时候,先对cost~m进行初始化,值为w[root],表示只取父亲的情况。

    之后对每个儿子进行dfs,每次都是两个for循环。

    for(m...j...cost)

       for(1...k....j-cost)  //儿子最多分配j-cost

    则最后结果就是dp[1][m],其中1是总root点。

    注意本题m可以等于0,所以在全部读入数据之后对0特判输出0,否则再dfs。

    #include "cstdio"
    #include "vector"
    #include "cstring"
    using namespace std;
    #define maxn 500
    int bug[maxn],w[maxn],head[maxn],n,m,u,v,tol;
    struct Edge
    {
        int to,next;
    }e[maxn*2];
    bool vis[maxn];
    int dp[maxn][maxn];
    void addedge(int u,int v)
    {
        e[tol].to=v;
        e[tol].next=head[u];
        head[u]=tol++;
    }
    void dfs(int root,int pre)
    {
        int i=root,cost=(bug[root]+19)/20;
        for(int i=cost;i<=m;i++) dp[root][i]=w[root];
        for(int a=head[root];a!=-1;a=e[a].next)
        {
            int t=e[a].to;
            if(t==pre) continue;
            dfs(t,root);
            for(int j=m;j>=cost;j--)
                for(int k=1;k<=j-cost;k++)
                    dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[t][k]);
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d%d",&n,&m)&&n>0)
        {
            memset(head,-1,sizeof(head));
            memset(dp,0,sizeof(dp));
            tol=0;
            for(int i=1;i<=n;i++)
                scanf("%d%d",&bug[i],&w[i]);
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&u,&v);
                addedge(u,v);
                addedge(v,u);
            }
            if(m==0) {printf("0
    ");continue;}
            dfs(1,1);
            printf("%d
    ",dp[1][m]);
        }
        return 0;
    }
    11488265 2014-08-19 12:44:12 Accepted 1011 62MS 1280K 1508 B C++ Physcal
  • 相关阅读:
    form表单提交方式
    docker overlay2 目录下文件夹占用空间过大
    基本操作:vscode快捷键
    基本操作:vscodegit使用和命令
    关闭win10“快速启动”功能
    在CentOS 7.4下配置VNC Server服务
    golang 百分比抽奖几率
    对新闻客户端APP的性能优化实战
    性能优化专题 OOM 与 内存优化
    centos 安装谷歌浏览器和selenium环境 李刚
  • 原文地址:https://www.cnblogs.com/neopenx/p/4031973.html
Copyright © 2020-2023  润新知