题意:有n个洞组成一棵树,你有m个士兵,你从1号房间开始攻打,每个洞有a个"bugs"和b的价值。你的一个士兵可以打20个"bugs",为了拿到这个洞的价值b你必须留下k个士兵消灭这个洞的所有"bugs"(k*20>="bugs"的数量,且留下的士兵不可以再去攻打其他的洞,且必须攻打了前面的洞才可以攻打后面的洞)。问你花费这m个士兵可以得到的最大价值是多少。
思路:树形DP入门..
#include<bits/stdc++.h> using namespace std; const int maxn = 110; int n,m; int w[maxn],v[maxn]; int dp[maxn][maxn]; bool vis[maxn]; vector<int>e[maxn]; void dfs(int p) { int temp = (v[p]+19)/20; for (int i = temp;i<=m;i++) dp[p][i]=w[p]; vis[p]=1; for (int i = 0;i<e[p].size();i++) { int vv = e[p][i]; if (vis[vv]) continue; dfs(vv); for (int j = m;j>=temp;j--) for (int k = 1;k<=j-temp;k++) dp[p][j]=max(dp[p][j],dp[p][j-k]+dp[vv][k]); } } int main() { while (scanf("%d%d",&n,&m),n!=-1||m!=-1) { for (int i = 0;i<=n;i++) e[i].clear(); memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); for (int i = 1;i<=n;i++) scanf("%d%d",&v[i],&w[i]); for (int i = 1;i<n;i++) { int a,b; scanf("%d%d",&a,&b); e[a].push_back(b); e[b].push_back(a); } if (m==0) { printf("0\n"); continue; } dfs(1); printf("%d\n",dp[1][m]); } }