hdu 1011 Starship Troopers

题意:一个树形的地图,每个点都有一定的怪物,你派出的一个士兵最多可以消灭20个怪物,并且每个士兵只能派遣一次,消灭怪物后可以获得该点的价值,只有一个点消灭所有怪物才能通过有n个点,m个士兵,从1点开始,求可以获得最多价值

树背包,dp[u][i]表示分配给以u节点的i个士兵的最大价值,只是u这个点必须打而已

#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
vector<int> g[maxn];
int n,m,val[maxn],w[maxn],dp[maxn][maxn];

void dfs(int u,int f){
    for(int i=val[u];i<=m;i++)dp[u][i]=w[u];
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v==f)continue;
        dfs(v,u);
        for(int k=m;k>=val[u];k--)
            for(int j=1;j<=k-val[u];j++)
                dp[u][k]=max(dp[u][k],dp[u][k-j]+dp[v][j]);
    }
}

int main(){
    freopen("in","r",stdin);
    ios::sync_with_stdio(false);
    while(cin>>n>>m,n!=-1||m!=-1){
        for(int i=1;i<=n;i++){
            cin>>val[i]>>w[i];g[i].clear();
            val[i]=(val[i]+19)/20;
        }
        for(int i=1;i<n;i++){
            int u,v;cin>>u>>v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        if(m==0){cout<<0<<endl;continue;}
        memset(dp,0,sizeof(dp));
        dfs(1,-1);
        cout<<dp[1][m]<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jihe/p/5830782.html