Poj--2486(树形DP)

2014-12-09 09:41:47

思路:题目很好理解,一开始毫无思路TAT....好像树上背包可搞。

  最终:dp[i][j][0] :表示从i出发,最多走j步,且最后回到i的最优解,dp[i][j][1]:表示从i出发,最多走j步,且最后不回到i的最优解。

    转移:dp[i][j+2][0] = max(dp[i][j+2][0],dp[i][j - k][0] + dp[son][k][0]) (从i出发到son,并且回到i)

        dp[i][j+1][1] = max(dp[i][j+1][1],dp[i][j - k][0] + dp[son][k][1]) (从i出发到son,不会到i,那么遍历除son外其他子节点时继续回到i (dp[i][j - k][0]))

       dp[i][j+2][1] = max(dp[i][j+2][1],dp[i][j - k][1] + dp[son][k][0])  (从i出发到son,并且回到i,然后再出发到其他儿子,最终不回i)

 1 /*************************************************************************
 2     > File Name: 2486.cpp
 3     > Author: Natureal
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Tue 09 Dec 2014 01:21:00 AM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 const int maxn = 210;
27 
28 int N,K;
29 int num[maxn];
30 int first[maxn],next[maxn * 2],ver[maxn * 2],ecnt;
31 int dp[maxn][maxn *  2][2];
32 
33 void Init(){
34     memset(dp,0,sizeof(dp));
35     memset(first,-1,sizeof(first));
36     ecnt = 0;
37 }
38 
39 void Add_edge(int u,int v){
40     next[++ecnt] = first[u];
41     ver[ecnt] = v;
42     first[u] = ecnt;
43 }
44 
45 void Solve(int fa,int p){
46     for(int i = first[p]; i != -1; i = next[i]){
47         int v = ver[i];
48         if(v == fa)
49             continue;
50         Solve(p,v);
51         for(int j = K - 1; j >= 0; --j){
52             for(int k = 0; k <= j; ++k){
53                 if(j + 2 <= K){
54                     dp[p][j + 2][0] = max(dp[p][j + 2][0],dp[p][j - k][0] + dp[v][k][0]);
55                     //留在其他son里
56                     dp[p][j + 2][1] = max(dp[p][j + 2][1],dp[p][j - k][1] + dp[v][k][0]);
57                 }
58                 dp[p][j + 1][1] = max(dp[p][j + 1][1],dp[p][j - k][0] + dp[v][k][1]);
59             }
60             //printf("liu %d , qita %d , ziji %d\n",dp[p][j + 2][0],dp[p][j + 2][1],dp[p][j + 1][1]);
61         }
62     }
63 }
64 
65 int main(){
66     int a,b;
67     while(scanf("%d%d",&N,&K) != EOF){
68         Init();
69         for(int i = 1; i <= N; ++i){
70             scanf("%d",num + i);
71             for(int j = 0; j <= K; ++j){
72                 dp[i][j][0] = dp[i][j][1] = num[i];
73             }
74         }
75         for(int i = 1; i < N; ++i){
76             scanf("%d%d",&a,&b);
77             Add_edge(a,b);
78             Add_edge(b,a);
79         }
80         Solve(0,1);
81         printf("%d\n",max(dp[1][K][0],dp[1][K][1]));
82     }
83     return 0;
84 }

 

posted @ 2014-12-09 09:47  Naturain  阅读(159)  评论(0编辑  收藏  举报