树型动态规划练习总结
类型一、多叉树转二叉树进行资源分配
例如:
* 例1. 选课:每门课可能有一门先选课,即某些课必须在另外的某节课被选之后才能选,每门课能得的学分不同,求最大学分。
* 例2. 通向自由的钥匙:可以从一个房间通向另外多个房间,通过每个房间所需的花费不同,得到的价值也不同,用最小花费获得最大价值。
这种题目的特点是需要在多叉树上进行资源的分配,对不同的子树分配不同的资源,以求最大价值。可以直接在多叉树上用背包的方式求解,但是更常用的方法是用左孩子右兄弟表示法转化为二叉树。
转化之后的通用状态转移方程:
用 f(i,j) 表示将总量为 j 的资源分配给以 i 为根节点的子树,则
f(i, j) = max{ f(i.left, k) + f(i.right, j-cost(i)-k) + value(i), f(i.right, j) },其中 k∈(0, j-cost(i))
解释一下上面的方程。对于每个节点 i 都有两种决策:
1. 在节点 i 消耗资源并获得相应价值,然后在节点 i 的子节点和兄弟节点中进行决策;
2. 忽略节点 i ,在 i 的兄弟节点(i.right)中进行决策。
以上两道例题的状态转移方程写法都与这种通用写法类似。
类型二、一个节点的不同状态
(这种类型不知道怎么叫)
例如:
* 例1. 警卫安排:在一个节点上安排警卫可以保证与其相邻的节点的安全,每个节点安排警卫的代价不同,在一棵树上用最小代价保证整棵树的安全。
* 例2. 没有上司的晚会:职员和他的直接上司不会同时出现在晚会,每个职员在晚会上的快乐程度不同,求晚会的最大快乐程度。
这种题目的特点是每个节点有各自不同的状态,如警卫安排中每个节点有三种状态:1. 自己设有警卫;2. 父节点设有警卫;3. 子节点设有警卫。例2中每个节点(职员)有两种状态:1. 参加;2. 不参加。
对每个节点的每个状态进行转移即可。
如例2:
用 f(i, 0) 表示 i 不参加晚会,用 f(i, 1) 表示 i 参加晚会,则
f(i, 0) = sum{ max{ f(j, 0), f(j, 1) } }
f(i, 1) = sum{ max{ f(j, 0) } }
(j 是 i 的子节点)
解释一下上面的两个方程:
当 i 参加晚会时,i 的下属必然不参加晚会;
当 i 不参加晚会时,i 的下属可以参加晚会也可以不参加晚会。
例1类似。
类型三、二叉树上的资源分配
是类型一的简化版,题目的模型即二叉树,不用进行转换就可以直接求解。