题意:一个树形的地图,每个点都有一定的怪物,你派出的一个士兵最多可以消灭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; }