Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15457 Accepted Submission(s): 4152
题意:n个房间m个士兵,接下来n行表示每个房间bug和收益,其中一个士兵能干掉20个bug,然后n-1行是房间之间连通情况,问m个人最大的收益
dp[i][j]表示根节点为i,j个士兵的收益,则dp[i][j] = max{dp[ i ][ j ], dp[ i ][j - k] + dp[ son[i] ][k] }
当一个房间的bug为0是也需要一个士兵,所以当m = 0时直接输出0
节点减一
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 #include <vector> 6 using namespace std; 7 const int MAX = 110; 8 int dp[MAX][MAX],vis[MAX],bug[MAX],p[MAX]; 9 vector<int> son[MAX]; 10 int n,m; 11 void dfs(int u) 12 { 13 vis[u] = true; 14 for(int i = bug[u]; i <= m; i++) 15 dp[u][i] = p[u]; 16 int tot = (int) son[u].size(); 17 for(int i = 0; i < tot; i++) 18 { 19 int v = son[u][i]; 20 if(vis[v]) 21 continue; 22 dfs(v); 23 for(int j = m; j >= bug[u]; j--) 24 { 25 for(int k = 1; k <= j - bug[u]; k++) 26 { 27 if(dp[u][j] < dp[u][j - k] + dp[v][k]) 28 dp[u][j] = dp[u][j - k] + dp[v][k]; 29 } 30 } 31 } 32 } 33 int main() 34 { 35 while(scanf("%d%d", &n, &m) != EOF) 36 { 37 if(n == -1 && m == -1) 38 break; 39 for(int i = 0; i < n; i++) 40 { 41 scanf("%d%d", &bug[i], &p[i]); 42 bug[i] = (bug[i] + 19) / 20; 43 } 44 for(int i = 0; i <= n; i++) 45 son[i].clear(); 46 for(int i = 0; i < n - 1; i++) 47 { 48 int a,b; 49 scanf("%d%d", &a, &b); 50 son[a - 1].push_back(b - 1); 51 son[b - 1].push_back(a - 1); 52 } 53 if(m == 0) 54 printf("0\n"); 55 else 56 { 57 memset(vis, false, sizeof(vis)); 58 memset(dp, 0, sizeof(dp)); 59 dfs(0); 60 printf("%d\n", dp[0][m]); 61 } 62 63 } 64 65 return 0; 66 }
HD 1011 Starship Troopers(树上的背包)
原文:http://www.cnblogs.com/zhaopAC/p/5183087.html