ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

POJ2486 Apple Tree(树形背包)

2022-06-18 12:00:28  阅读:108  来源: 互联网

标签:背包 Apple int max Tree POJ2486 回到 节点 dp


从每个节点u出发后有两种情况:回到u和不回到u。

dp数组设为三维,第一维是节点编号,第二维是从该节点开始走的步数,第三维1/0 表示是否回到该节点。

可以回到时:dp[u][j][1]=max(dp[u][j][1],dp[u][j-t][1]+dp[v][t-2][1]);

不能回到时,分为两种情况:1.最终停在v子树上 2.最终停在其他子树上。

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

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

我们要枚举j和t,j代表的意义上文提到了,t则表示在从u到v这棵子树上走的步数,那么j-t就是在其他子树上走的步数,每棵子树v都要被枚举,由此分析可以得到上面的三种情况。

之所以叫树形背包是因为枚举j和t的部分类似于背包问题,其中j是要倒推的,因为每个节点的苹果树只能摘一次,摘完就没有了。(参考01背包的倒推思想)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int M=210;
 6 int n,k,cnt;
 7 //dp[u][j][0]表示以u为根的树经过j步没有回到点u得到的最值
 8 //dp[u][j][1]表示以u为根的树经过j步回到点u得到的最值 
 9 int dp[M][M][2],val[M],head[M];
10 
11 struct edge{
12     int v,next;
13 }e[M<<1];
14 
15 void init(){
16     memset(head,0,sizeof(head));
17     memset(dp,0,sizeof(dp));
18     cnt=0;
19 }
20 
21 void add(int u,int v){
22     e[++cnt].next=head[u];
23     head[u]=cnt;
24     e[cnt].v=v;
25 }
26 
27 void dfs(int u,int fa){
28     for(int i=0;i<=k;i++)
29         dp[u][i][0]=dp[u][i][1]=val[u];
30     for(int i=head[u];i;i=e[i].next){
31         int v=e[i].v;
32         if(v==fa) continue;
33         dfs(v,u);
34         for(int j=k;j>=1;j--)//树形背包 
35             for(int t=1;t<=j;t++){
36                 dp[u][j][0]=max(dp[u][j][0],dp[u][j-t][1]+dp[v][t-1][0]);
37                 if(t>=2) dp[u][j][1]=max(dp[u][j][1],dp[u][j-t][1]+dp[v][t-2][1]);
38                 if(t>=2) dp[u][j][0]=max(dp[u][j][0],dp[u][j-t][0]+dp[v][t-2][1]);
39             }
40     }
41 }
42 
43 int main(){
44     int u,v;
45     while(~scanf("%d%d",&n,&k)){
46         init();
47         for(int i=1;i<=n;i++) scanf("%d",&val[i]);
48         for(int i=1;i<n;i++){
49             scanf("%d%d",&u,&v);
50             add(u,v);add(v,u);
51         }
52         dfs(1,-1);
53         printf("%d\n",max(dp[1][k][0],dp[1][k][1]));
54     }
55     return 0;
56 }

做这道题就是要从一个节点u分析,考虑他的情况(如本题回到与不回到),从而进一步分析每种可能的情况,得到方程。

标签:背包,Apple,int,max,Tree,POJ2486,回到,节点,dp
来源: https://www.cnblogs.com/yhxnoerror/p/16388039.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有