树形DP。这是个什么东西?为什么叫这个名字?跟其他DP有什么区别?

相信很多初学者在刚刚接触一种新思想的时候都会有这种问题。

没错,树形DP准确的说是一种DP的思想,将DP建立在树状结构的基础上。

既然说了这是一种思想,那么单讲的话,也讲不出什么东西来。所以我们结合具体题目进行讲解,希望大家可以在题目中领悟这种思想。

提到树形DP入门题,很多人都会提到没有上司的舞会这道题,的确,这道题堪称树形DP的典范,但是我个人认为,这道题的处理方式不够普遍,二叉苹果树这道题的处理方式相比之下更加普遍。下面我们就将结合这道题进行讲解。

题意很简单,每条边有一个权值,保留若干条边,求去掉边后根节点能够到达的所有边的权值和最大是多少。

看到这道题,也许大家会想到数字三角形这道题,但是这里的这棵树并不是一颗满二叉树,甚至也不是一颗完全二叉树,所以我们不能用数字三角形的处理方式来做这道题。那该怎么思考呢?很明显,这是一个树状结构,我们可以从这点出发来考虑。这道题明确给出了根的位置,也就确定了父子节点的关系,我们会发现,对于每个父节点的状态,都是由它的子节点转移过来的,所以我们大概可以得出这里有一个由子节点转移到父节点的状态转移方程,又因为父节点子树上选择的边数完全取决于子节点的子树选择的边数。

\(f[u][i]=max(f[u][i],f[u][i−j−1]+f[v][j]+w)\)

\(f[u][i]\)表示以\(u\)为根节点的子树选择\(i\)条边权值和最大为多少,这实际上就是一个背包。为什么两个\(f\)数组的边数为\(i-1\)条呢?因为我们若想取一颗子节点的子树上的边,那就必须取父节点与子节点相连的那条边。

我们下面来看代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#define ll long long
#define gc getchar
#define maxn 105
using namespace std; inline ll read(){
ll a=0;int f=0;char p=gc();
while(!isdigit(p)){f|=p=='-';p=gc();}
while(isdigit(p)){a=(a<<3)+(a<<1)+(p^48);p=gc();}
return f?-a:a;
} struct ahaha{
int w,to,next;
}e[maxn<<1];int tot,head[maxn];
inline void add(int u,int v,int w){
e[tot].w=w,e[tot].to=v,e[tot].next=head[u];head[u]=tot++;
}int n,m; int sz[maxn],f[maxn][maxn];
void dfs(int u,int fa){
for(int i=head[u];~i;i=e[i].next){
int v=e[i].to;if(v==fa)continue;
dfs(v,u);sz[u]+=sz[v]+1; //子树边数在加上子节点子树的基础上还要加一,也就是连接子节点子树的那条边
for(int j=min(sz[u],m);j;--j) //由于是01背包,所以要倒序DP
for(int k=min(j-1,sz[v]);k>=0;--k) //这一维正序倒序无所谓,但是把取min放在初始化里可以减少运算次数,算是一个优化的小习惯
f[u][j]=max(f[u][j],f[u][j-k-1]+f[v][k]+e[i].w);
}
} int main(){memset(head,-1,sizeof head);
n=read();m=read();
for(int i=1;i<n;++i){ //前向星存边,要存两边,便于读取
int u=read(),v=read(),w=read();
add(u,v,w);add(v,u,w);
}
dfs(1,-1);
printf("%d",f[1][m]);
return 0;
}

以上就是这道题的做法,你理解树形DP了吗?

所谓的树形DP,只不过是将一般DP的线性转移,变成了在树上进行转移,本质并无差别。

下面是几道本人筛选出的不错的树形DP的题目,有意者可以尝试一下

树上染色

时态同步

选课

没有上司的舞会

访问美术馆

战略游戏

茫茫人海相遇也算种缘分,点下推荐好不好QwQ

树形DP入门详解+题目推荐的更多相关文章

  1. 状压DP入门详解+题目推荐

    在动态规划的题型中,一般叫什么DP就是怎么DP,状压DP也不例外 所谓状态压缩,一般是通过用01串表示状态,充分利用二进制数的特性,简化计算难度.举个例子,在棋盘上摆放棋子的题目中,我们可以用1表示当 ...

  2. 数位DP入门详解+题目推荐

    \(update:2019-9-6\) 博客里某些东西没有解释清楚,完善了对应的解释 在开始之前,我们先来看一道题--题目链接 题目要求,相邻两位的差大于等于2,那么我们先来构造一个试一试. 比如说\ ...

  3. 【动态规划】树形DP完全详解!

    蒟蒻大佬时隔三个月更新了!!拍手拍手 而且是更新了几篇关于DP的文章(RioTian狂喜) 现在赶紧学习和复习一下树形DP.... 树形DP基础:Here,CF上部分树形DP练习题:Here \[QA ...

  4. HDU 1693 插头dp入门详解

    放题目链接   https://vjudge.net/problem/22021/origin 给出一个n*m的01矩阵,1可走0不可通过,要求走过的路可以形成一个环且可以有多个环出现,问有多少不同的 ...

  5. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  6. Redis快速入门详解

    Redis入门详解 Redis简介 Redis安装 Redis配置 Redis数据类型 Redis功能 持久化 主从复制 事务支持 发布订阅 管道 虚拟内存 Redis性能 Redis部署 Redis ...

  7. [置顶] xamarin android toolbar(踩坑完全入门详解)

    网上关于toolbar的教程有很多,很多新手,在使用toolbar的时候踩坑实在太多了,不好好总结一下,实在浪费.如果你想学习toolbar,你肯定会去去搜索androd toolbar,既然你能看到 ...

  8. 树形dp 入门

    今天学了树形dp,发现树形dp就是入门难一些,于是好心的我便立志要发一篇树形dp入门的博客了. 树形dp的概念什么的,相信大家都已经明白,这里就不再多说.直接上例题. 一.常规树形DP P1352 没 ...

  9. 【转载】SQL注入攻防入门详解

    滴答…滴答…的雨,欢迎大家光临我的博客. 学习是快乐的,教育是枯燥的. 博客园  首页  博问  闪存    联系  订阅 管理 随笔-58 评论-2028 文章-5  trackbacks-0 站长 ...

随机推荐

  1. 关于恶意说说自动在QQ空间转发的机制

    有些很讨厌的带链接说说,只要你在手机打开它,就会自动转发,内容极其不雅 一怒之下我决定看个究竟首先,在此页开头有此关键语句: <iframe src="http://rtb.map.q ...

  2. 使用web api开发微信公众号,调用图灵机器人接口(二)

    此文将分两篇讲解,主要分为以下几步 签名校验; 首次提交验证申请; 接收消息; 被动响应消息(返回XML); 映射图灵消息及微信消息; 此篇为第二篇. 被动响应消息(返回XML) 上一篇中,我们已经可 ...

  3. 百度ueditor 文本框

    所需配置(qui框架) <!--ueEditor编辑器start--> <script>  window.UEDITOR_HOME_URL = ctx+"/stati ...

  4. tomcat安装及使用详解

    常用软件安装及使用目录 资料链接:https://pan.baidu.com/s/1XOUlneFqt-_1tOLSmc-E1g     网盘分享的文件在此 1. Tomcat简介 Tomcat是一个 ...

  5. centos安装eclise启动报错

    A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be avail http://blog.csdn.net/u0 ...

  6. 基于NABCD评论作业-王者荣耀交流协会PSP DAILY

    一.根据(不限于)NABCD评论作品的选题   N(Need,需求):在我知道PSP DAILY这款软件的时候,就认为这款软件对于学习软件工程课的学生来说有很大的需要.对于需求来说,软件工程课程中的学 ...

  7. kafka启动报错:另一个程序正在使用此文件,进程无法访问。

    在Windows上启动kafka_2.12-1.1.0报以下错误:[2018-05-08 10:24:51,777] ERROR Failed to clean up log for __consum ...

  8. Scrum Meeting 2 -2014.11.2

    今天大家读完代码后又聚在了一块讨论了许多.确定了重点的任务和分工细节.提出了许多问题和改进的方案.还有讨论分析了关于团队作业 - 软件分析和用户需求调查,初步决定目标软件为必应的输入法和词典,团队为争 ...

  9. 实验三 敏捷开发和XP实验

    课程:Java程序设计实验   班级:1352             姓名: 于佳心           学号:20135206 成绩:               指导教师:娄嘉鹏         ...

  10. 第十二节 Linux下软件安装

    apt-get:apt-get使用各用于处理apt包的公用程序集,我们可以用它来在线安装.卸载和升级软件包等,下面列出一些apt-get包含的常用的一些工具 常用参数: 重新安装: 软件升级: