• HDU 1011 Starship Troopers(树上背包)


     

    题目大意

     

    有 n(1<n<=100) 个山洞,每个山洞中都有一些 bug,每个山洞中都有一定的概率包含一个 brain。所有的山洞形成一棵树

    现在给你 m(0<=m<=100) 个士兵,每个士兵都能消灭 20 个 bugs,并占领这个山洞

    山洞的入口的编号是 1

    问怎么安排士兵占领山洞才能使捕获 brain 的概率最大!

     

    做法分析

     

    典型的树上背包问题

    定义状态 f[u][P] 表示用 P 个士兵占领以 u 为根节点的子树所能获得的概率最大值

    状态转移就是一个树形DP过程

    目标状态就是 f[1][m]

     

    一个小trick:即使某个山洞的 bug 数量为 0,那么也至少需要 1 个士兵去获取 brain,所以当现在手上的士兵数量为 0 的时候,可以直接输出 0 了

    参考代码

     

    PS:我把所有点的编号都 -1 了

    HDU 1011
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <vector>
     5 
     6 using namespace std;
     7 
     8 const int N=101;
     9 
    10 int n, m;
    11 int bug[N], p[N], f[N][N];
    12 vector<int> adj[N];
    13 
    14 void DFS(int u, int pre)
    15 {
    16     for(int i=bug[u]; i<=m; i++) f[u][i]=p[u];
    17     int tot=(int)adj[u].size();
    18     for(int i=0; i<tot; i++)
    19     {
    20         int v=adj[u][i];
    21         if(v==pre) continue;
    22         DFS(v, u);
    23         for(int j=m; j>=bug[u]; j--)
    24             for(int k=1; k<=j-bug[u]; k++)
    25                 if(f[u][j]<f[u][j-k]+f[v][k]) f[u][j]=f[u][j-k]+f[v][k];
    26     }
    27 }
    28 
    29 int main()
    30 {
    31     while(scanf("%d%d", &n, &m), n!=-1 || m!=-1)
    32     {
    33         for(int i=0; i<n; i++)
    34         {
    35             scanf("%d%d", &bug[i], &p[i]);
    36             bug[i]=(bug[i]+19)/20;
    37         }
    38         for(int i=0; i<n; i++) adj[i].clear();
    39         for(int i=0, a, b; i<n-1; i++)
    40         {
    41             scanf("%d%d", &a, &b);
    42             adj[a-1].push_back(b-1);
    43             adj[b-1].push_back(a-1);
    44         }
    45         if(m==0)
    46         {
    47             printf("0\n");
    48             continue;
    49         }
    50         memset(f, 0, sizeof f);
    51         DFS(0, -1);
    52         printf("%d\n", f[0][m]);
    53     }
    54     return 0;
    55 }

    AC通道

    HDU 1011 Starship Troopers

  • 相关阅读:
    迭代合并排序算法
    appendChild和insertBefore的区别
    使用定时器处理数组
    正则表达式 删除string首尾的空白
    图片滚动
    数组合并法(IE7性能优化)
    赋值取值+arguments
    条件预加载(conditional advanceloading)
    Just a Note~
    腾讯马拉松复赛第一场
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/2951237.html
Copyright © 2020-2023  润新知