题目
思路
1. 树形 DP 动规数组的设置方法一般为 dp[u][i], u 为根节点, i 为可枚举的量(资源, 收益都有可能)
2. 树形 DP 一般都是多叉树转二叉树, 若孩子节点之间的地位不平等, 则 dp[u][i] 需要添加额外的维
3. 代码框架是 dfs 进行后序遍历, dfs(int pre, int u, int K)
4. 第一题 鬼吹灯. 经典树形 DP. dp[u][i] 表示在以 u 为根的节点花费 i 的时间最后回到点 u 所能达到的最大价值.
dp[u][i] = max(dp[u][i-k-2] + dp[j][k])
5. 第二题 电信. dp[u][i] 表示以 u 为根的树, 保留 i 个用户所能得到的最大收益
dp[u][i] = max(dp[u][i-k] + dp[j][k])
6. 第三题 修路. dp[u][i] 表示以 u 为根的树, 保留 i 个边所需要的最少切割数.
dp[u][i] = min(dp[u][i-k], dp[j][k])
7. 第四题 贿赂. 和上面相同, 但要注意, 有时候直接贿赂树根更加有效
8. 第五题 吃苹果. dp[u][i][0] 表示在以 u 为根的节点上分配 i 单位时间最终回到 u 所能吃到的最多苹果数; dp[u][i][1] 表示没能回到 u 所能吃到的最多苹果数
dp[u][i+2][0] = dp[u][i-k][0] + dp[v][k][0]
dp[u][i+1][1] = dp[u][i-k][0] + dp[v][k][1]
dp[u][i+2][1] = dp[u][i-k][1] + dp[v][k][0]
9. 第六题 将树切割尽可能平均的切割. 后序遍历即可