首页 > 代码库 > 树形dp入门

树形dp入门

POJ2342

一棵树,每个节点有权值,儿子与父亲不能同时取,求最大权值和

dp[i][0]表示不取,dp[i][1]表示取。

设j为i的儿子节点,dp[i][0] += max(dp[j][0], dp[j][1]),  dp[i][1] += dp[j][0];

 

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #define max(x, y) (x > y ? x : y)
 4 using namespace std;
 5 
 6 const int maxn = 6e3 + 10;
 7 int par[maxn];
 8 int dp[maxn][2];
 9 int n, u, v;
10 
11 void dfs(int node) {
12     for (int i = 1; i <= n; i++) {
13         if (par[i] == node) {
14             dfs(i);
15             dp[node][1] += dp[i][0];
16             dp[node][0] += max(dp[i][0], dp[i][1]);
17         }
18     }
19 }
20 
21 int main(int argc, const char * argv[]) {
22     while (~scanf("%d", &n)) {
23         memset(dp, 0, sizeof(dp));
24         int root = 1;
25         for (int i = 1; i <= n; i++) scanf("%d", &dp[i][1]);
26         while (scanf("%d%d", &u, &v), u + v) {
27             par[u] = v;
28             root = v;
29         }
30         dfs(root);
31         printf("%d\n", max(dp[root][0], dp[root][1]));
32     }
33     return 0;
34 }
View Code

 

树形dp入门