本篇截取自OI WIKI
以下面这道题为例,介绍一下树形 DP 的一般过程.
> 洛谷 P1352 没有上司的舞会
> 某大学有 𝑛 个职员,编号为 1 ∼𝑁.
> 他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数 aia_{i}ai ,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了.
> 所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数.
我们设 𝑓(𝑖,0/1) 代表以 𝑖 为根的子树的最优解(第二维的值为 0 代表 𝑖 不参加舞会的情况,1 代表 𝑖 参加舞会的情况).
对于每个状态,都存在两种决策(其中下面的 𝑥 都是 𝑖 的儿子):
上司不参加舞会时,下属可以参加,也可以不参加,此时有
𝑓(𝑖,0)=∑max(𝑓(𝑥,1),𝑓(𝑥,0))𝑓(𝑖,0) = ∑max {(𝑓(𝑥,1),𝑓(𝑥,0))} f(i,0)=∑max(f(x,1),f(x,0))
上司参加舞会时,下属都不会参加,此时有
𝑓(𝑖,1)=∑𝑓(𝑥,0)+ai𝑓(𝑖,1) =∑𝑓(𝑥,0) +ai f(i,1)=∑f(x,0)+ai
我们可以通过 DFS,在返回上一层时更新当前结点的最优解.
通常,树形 DP 状态一般都为当前节点的最优解.先 DFS 遍历子树的所有最优解,然后向上传递给子树的父节点来转移,最终根节点的值即为所求的最优解.