标签:
题意:
是有n个洞组成一棵树,你有m个士兵,你从1号房间开始攻打,每个洞有a个"bugs"和b的价值。你的一个士兵可以打20
个"bugs",为了拿到这个洞的价值b你必须留下k个士兵消灭这个洞的所有"bugs"(k*20>="bugs"的数量,且留下的士兵不可以再
去攻打其他的洞,且必须攻打了前面的洞才可以攻打后面的洞)。问你花费这m个士兵可以得到的最大价值是多少。
dp方程:
dp[p][j]=max(dp[p][j],dp[p][j-k]+dp[son[p] ][ k ])
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=110; 9 int b[maxn],v[maxn]; 10 vector<int> node[maxn]; 11 int n,m; 12 int dp[maxn][maxn]; 13 int vis[maxn]; 14 void dfs(int p) 15 { 16 int i,j,k; 17 int temp; 18 temp=(b[p]+19)/20; 19 for(i=temp;i<=m;i++) dp[p][i]=v[p]; 20 vis[p]=1; 21 for(i=0;i<node[p].size();i++) 22 { 23 int t=node[p][i]; 24 if(vis[t]) continue; 25 dfs(t); 26 for(j=m;j>=temp;j--) 27 { 28 for(k=1;k<=j-temp;k++) 29 { 30 dp[p][j]=max(dp[p][j],dp[p][j-k]+dp[t][k]); 31 } 32 } 33 } 34 } 35 int main() 36 { 37 int i,j,k; 38 //freopen("1.in","r",stdin); 39 while(scanf("%d%d",&n,&m)!=EOF) 40 { 41 if(n==-1&&m==-1) break; 42 for(i=0; i<=n; i++) node[i].clear(); 43 memset(dp,0,sizeof(dp)); 44 memset(vis,0,sizeof(vis)); 45 for(i=1;i<=n;i++) 46 { 47 scanf("%d%d",&b[i],&v[i]); 48 } 49 for(i=1;i<=n-1;i++) 50 { 51 int p,q; 52 scanf("%d%d",&p,&q); 53 node[q].push_back(p); 54 node[p].push_back(q); 55 } 56 if(m==0) {printf("0\n");continue;} 57 dfs(1); 58 printf("%d\n",dp[1][m]); 59 } 60 return 0; 61 }
标签:
原文地址:http://www.cnblogs.com/cnblogs321114287/p/4310437.html