树形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. c# url链接转成二维码图片,再转成byte[]二进制流,输出到前段ajax

    需要用到的 dll 添加引用 代码: //获取配置文件设置的url string urllink = ConfigurationManager.AppSettings["urllink&qu ...

  2. gith命令行使用之上传和删除

    git这个工具的功能很强大,而使用git bash的命令行来进行git工具的操作尤为重要.而且我个人认为,用命令行进行git工具的操作比起图形界面的git工具,要更容易理解.图形界面的那个叫Torto ...

  3. php 文件上传缩略图路径分析类

    <?php //文件上传时分析路径信息 //author:songzhenghe 2014-1-24 //version 0.1 class path_ana {     private $da ...

  4. Minor GC&Full GC&Major GC区别及触发条件

    Minor GC:从年轻代回收内存 触发条件 1.Eden区域满 ​ 2.新创建的对象大小 > Eden所剩空间 Full GC:清理整个堆空间,包括年轻代和老年代 触发条件 ​ 1.每次晋升到 ...

  5. Dubbo问题处理集合

    1 . 启动微服务的时候,报错信息如下: 核心:Can not lock the registry cache file /root/.dubbo/dubbo-registry-127.0.0.1.c ...

  6. CentOS 7 安装图形化界面及 Xshell 连接

    CentOS 比较适合用作服务器的系统,之前用过 CentOS 6,但是在配置 Nginx 的时候,发现很多语句版本7的系统都进行了更新,而且网上针对版本7的例子会更多一下,遂将系统换成版本7. 下载 ...

  7. 反爬虫和抗DDOS攻击技术实践

    导语 企鹅媒体平台媒体名片页反爬虫技术实践,分布式网页爬虫技术.利用人工智能进行人机识别.图像识别码.频率访问控制.利用无头浏览器PhantomJS.Selenium 进行网页抓取等相关技术不在本文讨 ...

  8. ualias命令详解

    基础命令学习目录首页 原文链接:https://blog.csdn.net/yexiangcsdn/article/details/82782667 个人分类: Linux Command 所属专栏: ...

  9. Python更新库

    查看系统里过期的python库,可以用pip命令 [root@vnode33 sim-enb-sgi]# pip list #列出所有安装的库 Package Version ------------ ...

  10. iOS - Bundle 资源文件包生成和常见资源文件使用

    1.Bundle 文件 Bundle 文件,就是资源文件包.我们将许多图片.XIB.文本文件组织在一起,打包成一个 Bundle 文件.方便在其他项目中引用包内的资源. Bundle 文件是静态的,也 ...