HDU 1561 The more, The Better (树形dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561

题意不讲了,中文。

树形背包,可以以0为总root,m++。dp[i][j] 表示以i节点为root 攻克j个城堡的价值最大是多少。 dp[i][j] = max(dp[i][j] , dp[i.son][k] + dp[i][j - k])

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 using namespace std;
 6 const int N = 205;
 7 int dp[N][N], n, m, a[N];
 8 vector <int> G[N];
 9 
10 void init(int n) {
11     for(int i = 0; i <= n; ++i) {
12         G[i].clear();
13     }
14     memset(dp, 0, sizeof(dp));
15 }
16 
17 void dfs(int u, int p) {
18     for(int i = 1; i <= m; ++i) {
19         dp[u][i] = a[u];
20     }
21     for(int i = 0; i < G[u].size(); ++i) {
22         int v = G[u][i];
23         if(v == p)
24             continue;
25         dfs(v, u);
26         for(int j = m; j >= 1; --j) { //类似背包,倒着来取值可以唯一
27             for(int k = 1; k < j; ++k) {
28                 dp[u][j] = max(dp[u][j], dp[v][j - k] + dp[u][k]);
29             }
30         }
31     }
32 }
33 
34 int main()
35 {
36     while(~scanf("%d %d", &n, &m) && (n || m)) {
37         int u, v;
38         init(n);
39         for(int i = 1; i <= n; ++i) {
40             scanf("%d %d", &u, &v);
41             G[u].push_back(i);
42             a[i] = v;
43         }
44         ++m;
45         dfs(0, -1);
46         printf("%d\n", dp[0][m]);
47     }
48     return 0;
49 }

  

posted @ 2016-10-09 20:49  Recoder  阅读(202)  评论(0编辑  收藏  举报