前言
本篇的代码均是由邻接表来进行存储,大概在还会再来一个用链式前向星版的吧~ (下次一定)
ps: 笔者已经很用心的在打 L a T e X LaTeX LaTeX了,但还是不够规范,望路过的大巨佬们多多指正
概念
度娘说
树形动态规划问题可以分解成若干相互联系的阶段,在每一个阶段都要做出决策,全部过程的决策是一个决策序列。要使整个活动的总体效果达到最优的问题,称为多阶段决策问题。
感觉好像并不明白她在说什么
其实笔者个人理解,树形DP更像是记忆化搜索,各个节点都像树一样连接着。(无环图)树形DP顾名思义就是像树一样的DP,在有n个节点的时候,有n-1条边连接着。
such as this
在解决树形DP的问题时,我们通常以节点从深至浅作为阶段,同时以递归来实现。就像后序遍历一样。
那么树形DP有什么作用呢?下面引出三种最版的题(也是今天笔者将要在本篇中写的)。
- 最大独立子集
- 树的重心
- 树的直径
最大独立子集
什么是最大独立子集呢?让我们来引出一道题来看看。
没有上司的晚会
题目描述
Ural大学有N个职员,编号为1~N。他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。每个职员有一个快乐指数。现在有个周年庆宴会,要求与会职员的快乐指数最大。但是,没有职员愿和直接上司一起参加宴会。
输入格式
第一行一个整数N。(1≤N≤6000)
接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128≤Ri≤127)
接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。
最后一行输入0,0。
输出格式
第1行:输出最大的快乐指数。
样例
样例输入
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
样例输出
5
从上题中我们就可以看见,对于每个节点,如果选中了它,就不可能选它的父亲节点和儿子节点。那么对于每一个节点我们就有了两种状态,选与不选。
设第i个为 d p [ i ] dp[i] dp[i], d p [ i ] [ 1 ] dp[i][1] dp[i][1]表示选它自己 d p [ i ] [ 0 ] dp[i][0] dp[i][0]表示不选它自己
那么状态转移方程就显而易见了
d p [ i ] [ 0 ] = ∑ m a x ( d p [ j ] [ 0 ] , d p [ j ] [ 1 ] ) — — — j ∈ s o n ( i ) dp[i][0] = \sum{max_(dp[j][0],dp[j][1])} ——— j\in{son(i)} dp[i][0]=∑max(dp[j][0],dp[j][1])———j∈son(i)
d p [ i ] [ 1 ] = ∑ d p [ j ] [ 0 ] — — — j ∈ s o n ( i ) dp[i][1] = \sum{dp[j][0]} ——— j\in{son(i)} dp[i][1]=