动态规划(四)树形DP
Contents
在树上设计动态规划算法时,一般按照节点的深度从深到浅,(或者说子树从小到大)的顺序作为 DP 的”阶段“。DP 的状态表示中,第一维通常是节点编号。
求解树形动态规划时,往往采用递归的方式进行。对于每个节点 $x$ ,先递归遍历处理其每个子节点,在回溯时,从 $x$ 的子节点向节点 $x$ 进行状态转移。
没有上司的舞会
问题
Ural大学有 $N$ 名职员,编号为 1~N。他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。每个职员有一个快乐指数,用整数 $H_i$ 给出,其中 $1\leq i\leq N$。现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
分析
$F[x][0]$ 表示 $x$ 不参加舞会时,以 $x$ 为根的子树能够获得的最大的快乐值。
$F[x][1]$ 表示 $x$ 参加舞会时,以 $x$ 为根的子树能够获得的最大的快乐值。
$y_1, y_2,…,y_i,…$ 表示 $x$ 的直接下属。
当 $x$ 不参加舞会时。他的下属可以参加也可以不参加舞会。因此得出状态转移方程:
$$
F[x][0] = \sum \limits_{y \in son(x)} max(F[y_i][0], F[y_i][1]);
$$
当 $x$ 参加舞会时,他的直接下属都不参加舞会,因此得到状态转移方程:
$$
F[x][1] = H[x] + \sum \limits_{y\in son(x)}F[y_i][0];
$$
目标 $ans = max(F[root][1], F[root][0]);$
代码
1 |
|
Author: Hatton.Liu
Link: http://hattonl.github.io/2020/02/15/dynamic-programming-3/
License: 知识共享署名-非商业性使用 4.0 国际许可协议