树形DP是WHAT?
就是树上的DP呗 :-p
HOW TO DP?
给定一棵有N个节点的树(通常是无根树,也就是有N-1条无向边),我们可以任选一个节点为根节点,从而定义出每个节点的深度和每棵子树的根。
在树上设计动态规划算法时,一般就以节点从深到浅(子树从小到大)的顺序作为DP的“阶段”。DP的状态表示中,第一维通常是节点编号(代表以该节点为根的子树)。大多数时候,我们采用递归的方式实现树形动态规划。对于每个节点x,先递归在它的每个子节点上进行DP,在回溯时,从子节点向节点x进行状态转移。
经典例题
1、最大独立子集:
最大独立子集的定义是,对于一个树形结构,所有的孩子和他们的父亲存在排斥,也就是如果选取了某个节点,那么会导致不能选取这个节点的所有孩子节点。一般询问是要求给出当前这颗树的最大独立子集的大小(被选择的节点个数)。
例题:没有上司的舞会
我们设 d p [ i ] [ 1 ] dp[i][1] dp[i][1]表示 i i i要来的情况下以 i i i为根节点的子树的最大快乐值
d p [ i ] [ 0 ] dp[i][0] dp[i][0]表示 i i i不来的情况下以 i i i为根节点的子树的最大快乐值
若 i i i要来,那么他的每一个子节点都只能不来, d p [ i ] [ 1 ] = ∑ d p [ j ] [ 0 ] , j 为 i 的 子 节 点 dp[i][1]=\sum dp[j][0],j为i的子节点 dp[i][1]=∑dp[j][0],j为i的子节点
如果ta不来,那么他的每个子节点就可来可不来, d p [ i ] [ 0 ] = ∑ m a x ( d p [ j ] [ 0 ] , d p [ j ] [ 1 ] ) , j 为 i 的 子 节 点 dp[i][0]=\sum max(dp[j][0],dp[j][1]),j为i的子节点 dp[i][0]=∑max(dp[j][0],dp[j][1]),