POJ 2486 Apple Tree(树形dp)

http://poj.org/problem?id=2486

题意:

有n个点,每个点有一个权值,从1出发,走k步,最多能获得多少权值。(每个点只能获得一次)

 

思路:

从1点开始,往下dfs,对于每个结点,把时间分配给它的子节点,然后求一个最大值。

但是要注意的是,它有可能会走了之后然后又走回到父亲结点,这样的话,状态转移方程需要多考虑一下。

d【u】【j】【0/1】表示从u结点出发走 j 时所能获得的最大权值(0/1表示是否返回u结点)。

 d[u][j][0]=max(d[u][j][0],d[u][j-t][0] + d[v][t-2][0]); 
 d[u][j][1]=max(d[u][j][1],d[u][j-t][0] + d[v][t-1][1]);
 d[u][j][1]=max(d[u][j][1],d[u][j-t][1] + d[v][t-2][0]);

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn = 500+5;
17 
18 int n, k;
19 
20 int val[maxn];
21 int vis[maxn];
22 
23 vector<int> g[maxn];
24 
25 int d[maxn][maxn][2];
26 
27 void dfs(int u)
28 {
29     vis[u]=1;
30     for(int i=0;i<g[u].size();i++)
31     {
32         int v=g[u][i];
33         if(vis[v]) continue;
34         dfs(v);
35         for(int j=k;j>=1;j--)
36         {
37             for(int t=1;t<=j;t++)
38             {
39                 d[u][j][0]=max(d[u][j][0],d[u][j-t][0]+d[v][t-2][0]);
40                 d[u][j][1]=max(d[u][j][1],d[u][j-t][0]+d[v][t-1][1]);
41                 d[u][j][1]=max(d[u][j][1],d[u][j-t][1]+d[v][t-2][0]);
42             }
43         }
44     }
45 }
46 
47 int main()
48 {
49     //freopen("in.txt","r",stdin);
50     while(~scanf("%d%d",&n, &k))
51     {
52         for(int i=1;i<=1000;i++)  g[i].clear();
53         memset(d,0,sizeof(d));
54 
55         for(int i=1;i<=n;i++)
56         {
57             scanf("%d",&val[i]);
58             for(int j=0;j<=k;j++)
59                 d[i][j][0]=d[i][j][1]=val[i];
60         }
61 
62         for(int i=1;i<n;i++)
63         {
64             int u,v;
65             scanf("%d%d",&u,&v);
66             g[u].push_back(v);
67             g[v].push_back(u);
68         }
69 
70         memset(vis,0,sizeof(vis));
71         dfs(1);
72         printf("%d\n",max(d[1][k][0],d[1][k][1]));
73     }
74     return 0;
75 }

 

posted @ 2017-06-27 15:14  Kayden_Cheung  阅读(164)  评论(0编辑  收藏  举报
//目录