hdu_1011

n个洞穴,m个骑兵

每个骑兵最多可以打赢20个虫子

每个洞穴中打架的骑兵不能到其他洞穴

每个洞穴有一定的概率存在brain

合理支配m个骑兵,获取最大收益(最大抓住brain的概率)

// hdu 1011

// tree dp

// Feb.16 2015



#include <cstdio>

#include <vector>

#include <cstring>

#include <cmath>

#include <algorithm>



#define MAXN 111



std::vector<int> tunnel[MAXN];

int n, m, dp[MAXN][MAXN], bugs[MAXN], possi[MAXN];

// dp(num)(i) is the total possibility assign (i) Troopers to capture

// the tree whose root is (num)

bool vis[MAXN];



void dfs(int num)

{

    

    vis[num] = true;



    // for the cave numbered (num)

    // at least ( ceil(bugs[num]/20) ) Troopers are need 

    for(int i = bugs[num]; i <= m; ++i)

        dp[num][i] = possi[num];



    for(int i = 0; i < tunnel[num].size(); ++i){



        if(vis[ tunnel[num][i] ] == true)

            continue;



        dfs( tunnel[num][i] );

        // 对于一个根节点编号为num的子树

        // j为num节点的指派Trooper数量 

        // k为除num节点以外其他节点上Trooper数量

        for(int j = m; j >= bugs[num]; --j)

            for(int k = 1; k + bugs[num] <= j; ++k)

                dp[num][j] = std::max( dp[num][bugs[num]], dp[num][bugs[num]] + dp[ tunnel[num][i] ][k] );



    }

}



int main(int argc, char const *argv[])

{

    // freopen("in", "r", stdin);

    while(scanf("%d%d", &n, &m)){

        if(n == -1 && m == -1)

            return 0;

        memset(dp, 0, sizeof(dp));

        memset(vis, false, sizeof(vis));

        for(int i = 1; i <= n; ++i){

            scanf("%d%d", bugs+i, possi + i);

            bugs[i] = ceil(double(bugs[i])/20);

            // transform how many bugs into how many Troopers can defeat bugs in the cave

            tunnel[i].clear();

        }

        for(int i = 1, a, b; i < n; ++i){

            scanf("%d%d", &a, &b);

            tunnel[a].push_back(b);

            tunnel[b].push_back(a);

        }



        // if there is 0 bug in a cave 

        // we still need at least 1 Trooper to capture this cave

        if( m == 0 ){

            printf("0\n");

            continue;

        }

        

        dfs(1);

        // the aim status

        printf("%d\n", dp[1][m]);

    }

    return 0;

}

 

你可能感兴趣的:(HDU)