通过这道题对树形背包理解更深一步......

有几个地方需要注意:

1.本题数据结构为森林,需增加一个超根作为根节点,M+=1(后面解释)。

2.本题有拓扑序的限制,通过vector建成的一棵树中,必须父节点选择了之后才可以往下选择孩子节点。

3.在以v为根的子树中选择k个节点,k必然小等于v的子树大小,所以dfs过程中维护子树大小并进行优化,效率会有很大提升。

关键在于dp过程中如何保证第2点:

dp[u][j]表示在u为根的子树中选择j个点所得最大值,将边界条件设为dp[u][1]=val[u],这样就保证了在u为根的子树中选择1个点时只能是选择他自己,这样就能解决拓扑序的限制,我们的求解目标就是dp[0][M],注意这个M是加1过的,因为我们增加一个超根,我们只有在选择超根后才能往下选,所以M要加1,且超根是没有权值的,所以对最后答案也就没有影响。

如何理解树形背包:回想背包的特点是什么,枚举i物品时前i-1个已经求解,所以相当于是在原来的基础上在更新最优解(这也是大多数DP的特点),我们在处理u节点时,首先求解到一棵子树v1,通过v1更新了dp[u][ ],那么后面的v2,v3...也就基于前面的结果再次求解,最后能得到dp[u][ ]的最优解,代码类似于分组背包,还要注意倒推,因为每个节点只能被选1次。

 1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 #include<vector>
5 using namespace std;
6 const int N=200+10;
7 int val[N],dp[N][N];
8 vector<int>E[N];
9
10 int dfs(int u,int M){//返回以u为根的子树大小
11 dp[u][1]=val[u];
12 int sizeu=1,sizev=0;
13 for(int i=0;i<E[u].size();i++){
14 int v=E[u][i];
15 sizev=dfs(v,M-1);
16 for(int j=M;j>=1;j--)//类似分组背包倒推
17 for(int k=1;k<=sizev&&k<j;k++)
18 dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k]);
19 sizeu+=sizev;
20 }
21 return sizeu;
22 }
23
24 int main(){
25 int N,M;
26 while(~scanf("%d%d",&N,&M),N+M){
27 for(int i=0;i<=N;i++) E[i].clear();
28 memset(dp,0,sizeof(dp));
29 M++;//增加超根后,M+1
30 val[0]=0;
31 int u;
32 for(int i=1;i<=N;i++){
33 scanf("%d%d",&u,&val[i]);
34 E[u].push_back(i);
35 }
36 dfs(0,M);
37 printf("%d\n",dp[0][M]);
38 }
39 return 0;
40 }

HDU1561 The more, The Better(树形背包)的更多相关文章

  1. hdu1561 The more, The Better 树形DP+分组背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路: 典型的树形背包题目: 定义dp[i][j]表示以i为根节点,攻打j个城堡的获得的财宝的最 ...

  2. HDU1561 The more ,The better (树形背包Dp)

    ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先 ...

  3. poj2486Apple Tree[树形背包!!!]

    Apple Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9989   Accepted: 3324 Descri ...

  4. cdoj 1136 邱老师玩游戏 树形背包

    邱老师玩游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1136 Desc ...

  5. HDU 1011 树形背包(DP) Starship Troopers

    题目链接:  HDU 1011 树形背包(DP) Starship Troopers 题意:  地图中有一些房间, 每个房间有一定的bugs和得到brains的可能性值, 一个人带领m支军队从入口(房 ...

  6. poj 1155 TELE (树形背包dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接: poj-1155 题意 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构, ...

  7. bzoj 4813: [Cqoi2017]小Q的棋盘 [树形背包dp]

    4813: [Cqoi2017]小Q的棋盘 题意: 某poj弱化版?树形背包 据说还可以贪心... #include <iostream> #include <cstdio> ...

  8. [HAOI2015]树上染色(树形背包)

    有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之间的距离加 ...

  9. Luogu 1273 有线电视网 - 树形背包

    Description 树形背包, 遍历到一个节点, 枚举它的每个子节点要选择多少个用户进行转移. Code #include<cstring> #include<cstdio> ...

随机推荐

  1. [apue] 文件中的空洞

    空洞的概念 linux 上普通文件的大小与占用空间是两个概念,前者表示文件中数据的长度,后者表示数据占用的磁盘空间,通常后者大于前者,因为需要一些额外的空间用来记录文件的某些统计信息或附加信息.以及切 ...

  2. 后端统一处理返回前端日期LocalDateTime格式化去T,Long返回前端损失精度问题

    一.前言 我们在实际开发中肯定会遇到后端的时间传到前端是这个样子的:2022-08-02T15:43:50 这个时候前后端就开始踢皮球了,!! 后端说:前端来做就可! 前端说:后端来做就可! 作为一名 ...

  3. 产品 | GreatSQL,打造更好的MGR生态

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 用 ...

  4. Linux入门操作介绍

    Linux 是由unix衍生而来(小知识:mac也是使用unix核心),由全世界的程序员一起开发的开源系统.如今基于linux已经有了很多版本,我们后面使用的就是衍生版本之一的Ubuntu. Ubun ...

  5. 源码解析springbatch的job是如何运行的?

    202208-源码解析springbatch的job是如何运行的? 注,本文中的demo代码节选于图书<Spring Batch批处理框架>的配套源代码,并做并适配springboot升级 ...

  6. Spring的简单使用(3)

    一:SM框架的整合: 所需要的依赖: <dependency> <groupId>junit</groupId> <artifactId>junit&l ...

  7. 论语音社交视频直播平台与 Apache DolphinScheduler 的适配度有多高

    在 Apache DolphinScheduler& Apache ShenYu(Incubating) Meetup 上,YY 直播 软件工程师 袁丙泽 为我们分享了<YY直播基于Ap ...

  8. BZOJ1787/Luogu4281: [Ahoi2008]Meet 紧急集合

    画画图可知,三点\(lca\)必有两相同,\(a,b,c\)距离为\(dis_a + dis_b + dis_c - dis_{lca(a,b)} - dis_{lca(b,c)} - dis_{lc ...

  9. Git 02 安装

    参考源 https://www.bilibili.com/video/BV1FE411P7B3?spm_id_from=333.999.0.0 版本 本文章基于 Git 2.35.1.2 这里以安装 ...

  10. java-引用数组、继承、super关键字

    1.引用类型数组: 1)   Cell[] cells = new Cell[4];   cells[0] = new Cell(2,5); cells[1] = new Cell(2,6); cel ...