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

有几个地方需要注意:

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. VP视频结构化框架

    完成多路视频并行接入.解码.多级推理.结构化数据分析.上报.编码推流等过程,插件式/pipe式编程风格,功能上类似英伟达的deepstream和华为的mxvision,但底层核心不依赖复杂难懂的gst ...

  2. HtmlAgilityPack中使用xpath获取属性值

    HtmlAgilityPack介绍 HtmlAgilityPack是一个专门用来解析Html的库,它可以使用xml的方式来解析html. 有人说了,html本身不就是xml?是的,html就是xml, ...

  3. canal-1.1.5实时同步MySQL数据到Elasticsearch

    一.环境准备 1.jkd 8+ 2.mysql 5.7+ 3.Elasticsearch 7+ 4.kibana 7+ 5.canal.adapter 1.1.5 二.部署 一.创建数据库CanalD ...

  4. 简短截说阐述redis中事务的使用

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_127 我们知道,在关系型数据库中,比如mysql,如果要使用事务,首先向数据库服务器发送 BEGIN ,然后执行各个相互一致的写操 ...

  5. MVCC多版本并发控制的理解

    前置知识 当前读与快照读 当前读 什么是当前读:读取的是最新的数据,不会读到老数据. 何时触发:update.insert.delete.select lock in share mode.selec ...

  6. LuoguP2217 [HAOI2007]分割矩阵 (DP + memorized search)

    int n,m,tim; int mp[N][N], sum[N][N]; double ave,dp[N][N][N][N][N]; inline double DP(int a,int b,int ...

  7. Spring源码 06 IOC refresh方法1

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  8. Java NIO全面详解(看这篇就够了)

    很多技术框架都使用NIO技术,学习和掌握Java NIO技术对于高性能.高并发网络的应用是非常关键的@mikechen NIO简介 NIO 中的 N 可以理解为 Non-blocking,不单纯是 N ...

  9. 深入理解Spring事件机制(一):广播器与监听器的初始化

    前言 Spring 从 3.x 开始支持事件机制.在 Spring 的事件机制中,我们可以令一个事件类继承 ApplicationEvent 类,然后将实现了 ApplicationListener ...

  10. Oracle-视图,约束

    试图:试图是数据库对象之一视图在sql语句中体现的角色与表一致,但它不是一张真是存在的表,只是对应了一个查询语句的结果集当试图对应的子查询中含有函数或者表达式时,那么必须指定别名试图根据对应的子查询分 ...