树形DP
DP[i][j] 一般第一维表示节点编号(代表以此节点为根节点的子树) 对于每个节点,一般先递归处理他的子节点,在回溯时对根节点转移, 在做树形dp的题目的时候,最优子结构体现的非常明显。
树形背包
树形背包除了以节点编号作为第一维,通常我们也像线性dp那样,把当前背包的体积作为第二维,在状态转移时,我们处理的就是一个分组背包(每组至少取一个)问题,注意在进行状态转移时要保证一个儿子节点只可以转移一种状态
树形DP题目
HDU 1520 Anniversary party
题意:给定一棵关系树,每个节点有个权值,子节点和父节点不能同时选,问最后能选的最大价值是多少?
思路:由于子节点与父节点不能同时选,有人可能会用贪心思想,二者选其一肯定最优。其实不然,有可能父节点和子节点都不选,而要选子孙节点。不过只要再往深点想下,就可以得出动态规划的解法。每个节点要么选要么不选,和大多数选不选动归一样,来个dp[i][2],0表示不选,1表示不选,那我们只要从叶子节点往根结点不断更新dp[i][0]和dp[i][1]就可以了。
dp[u][0]+=max(dp[v][0],dp[v][1]); dp[u][1]+=dp[v][0];
HDU 2196 Computer
题意:给一棵树,每条树边都有权值,问从每个顶点出发,经过的路径权值之和最大为多少?每条树边都只能走一次
思路:节点u 最大值有二个可能 二个儿子节点的最长链 或者 一个儿子节点最长链和父亲节点最长链(不包括节点u)
二个儿子节点的最长链可以很容易求出来,但是父亲节点的最长链就求不出来了,但是如果我们知道父亲节点的 二个最大儿子节点链呢?进行二次dfs即可 第一次dfs求出每个节点的二个儿子 最长链 第二次dfs利用第一次dfs求出来的二个最长链跟新就行了
CodeForces 219D Choosing Capital for Treeland
题意:给一颗树,树的边是有向的,让你选一个节点,这个节点能到达所有的节点,问你最少要反转多少条边
思路:dp[u] 表示以u为根节点最少要反转的边数,假设节点u为根节点,状态转移方程很容易想到