标签:
题意:
给定n个定点和m个士兵,n个定点最终构成一棵树,每个定点有一定x个bugs和y个value,每20个bug需要消耗一个士兵,不足20也消耗一个,然后最终收获y个value,只有父节点被占领后子节点才有被占领的可能。
DP状态转移方程:
dp[p][j]=max(dp[p][j],dp[p][j-k]+dp[t][k]);
看的王大神的代码,DFS写的,先从叶子节点开始向上遍历进行动态规划,自己看了dp方程也没写出来。。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <vector> 5 #include <algorithm> 6 using namespace std; 7 #define Max 102 8 struct node 9 { 10 int bugs,val; 11 }cav[Max]; 12 vector<int> node[Max]; 13 int n,m; 14 int vis[Max],dp[Max][Max]; 15 int a,b; 16 void dfs(int p) 17 { 18 int i,j,k; 19 vis[p]=1; 20 int temp=(cav[p].bugs+19)/20; 21 for(i=temp;i<=m;i++) 22 dp[p][i]=cav[p].val; 23 for(i=0;i<node[p].size();i++) 24 { 25 int t=node[p][i]; 26 if(vis[t]) 27 continue; 28 dfs(t); 29 for(j=m;j>=temp;j--) //回溯时完成对该点的动态规划 30 for(k=1;k<=j-temp;k++) 31 dp[p][j]=max(dp[p][j],dp[p][j-k]+dp[t][k]); //保证父节点能够占领 32 } 33 return; 34 } 35 int main() 36 { 37 int i,j; 38 freopen("in.txt","r",stdin); 39 while(scanf("%d%d",&n,&m)!=EOF) 40 { 41 if(n==-1&&m==-1) 42 break; 43 memset(vis,0,sizeof(vis)); 44 memset(dp,0,sizeof(dp)); 45 for(i=0;i<=n;i++) node[i].clear(); 46 for(i=1;i<=n;i++) 47 scanf("%d%d",&cav[i].bugs,&cav[i].val); 48 for(i=0;i<n-1;i++) 49 { 50 scanf("%d%d",&a,&b); 51 node[a].push_back(b); 52 node[b].push_back(a); 53 } 54 if(m==0) 55 { 56 printf("0\n"); 57 continue; 58 } 59 dfs(1); 60 printf("%d\n",dp[1][m]); 61 } 62 return 0; 63 }
Starship Troopers(HDU 1011 树形DP)
标签:
原文地址:http://www.cnblogs.com/a1225234/p/5232271.html