树形 dp 做题记录

P3177 [HAOI2015] 树上染色

  • 考虑每一条边的贡献,就会发现这个贡献其实只和子树内的黑点的数量有关

  • 那么设 dp[u][num] 表示 u 节点子树内有 num 个黑点的最大收益

P2607 [ZJOI2008] 骑士

  • 可以发现最后的图就是一个基环森林,考虑一颗基环树怎么解决

  • 对于一颗基环树,考虑找到环上的一个点,然后断开换上的一条边

  • 然后就是一颗树了,对于一棵树就很好求了,最后我们强制根节点不选,那么答案仍然是合法的

  • 还有种情况就是强制那个和根之前相连的节点不选,然后再做一次,这样答案仍然合法

P4438 [HNOI/AHOI2018]道路

  • 看到一个条件,对于一个乡村可以通过不超过 40 条路到达首都

  • f[u][i][j] 表示节点 u 上面修建了 i 条公路和 j 条铁路,子树种的最小值

  • 那么每次先便遍历子树,然后对于自己枚举 i,j ,然后有两种选择,一种是修建左边,一种是修建右边

P1131 [ZJOI2007] 时态同步

  • 对于一个节点,自己祖先的路径只会统一修改自己的子树,所以我们对于每个节点,都要将自己所有的儿子修改到同一个时间

P1270 “访问”美术馆

  • 因为每条路要被走 2 次,所以一开始权值乘二

  • 对于每个节点维护 dp[u][time] 表示从这个节点下去还剩 time 的时间能得到的最多的画

P2491 [SDOI2011] 消防

  • 这个路径一定是在直径上,那么就可以把这个题目抽象成一个序列(直径)上的问题

  • 可以考虑用尺取法确定一个区间,对于这个区间的最大值就是左边右边中间,左右的可以预处理,对于中间的可以考虑单调队列维护

  • 那么整体的复杂度就是 O(n)

  • 我一开始想的是二分,但是麻烦一点

P4253 [SCOI2015]小凸玩密室

  • 这个题目一个很不好做的点在于有后效性,也就是当前的选择会影响到后面的选择

  • 对于一个节点为开始的话,肯定是先点亮自己,然后点亮一颗子树,再点亮另一颗子树,然后再点亮父亲,点亮父亲的另一颗子树,点亮父亲的父亲....

  • 对于这个节点不只要考虑子树中要是最小,还要考虑从子树中的一个叶节点到达父亲的一个路径长度

  • 既然有后效性,那么我们就将这个后效加入到状态中(事实上对于这一类有后效的 dp 可以考虑加上后效这一状态,或者更简单的直接加上会对后面造成的影响)

  • 对于一个叶子节点,下一步要么走到一个祖先,要么走到一个祖先的另一个儿子

  • 那么对于两者我们都保存,因为是一个完全二叉树,所以只会有 log 的祖先

  • f[u][i] 表示节点 u 遍历自己的子树完了后从子树中的一个叶子节点,到达第 i 个祖先的最小价值

  • g[u][i] 表示节点 u 遍历自己的子树完了后从子树中的一个叶子节点到达第 i 个祖先的另一个儿子的最小价值

  • 状态设出来了,转移方程就从儿子转移

  • 考虑最后一个节点作为第一个点亮的节点,那么这个节点肯定是先点亮自己的子树,然后点亮父亲,点亮父亲的另一个儿子,然后点亮父亲的父亲

  • 而这个过程很明显可以用我们刚刚求的数组来解决

  • 对于每个节点都假设为最初的节点

  • 总的复杂度就是 O(nlogn)

一些小 trick

  • 看到树了,考虑一下树形 dp

  • 一般都会有结点这个维度,一般都是考虑一个子树,然后考虑怎么从儿子转移

  • 完全二叉树的高度是 log

posted @   Kzos_017  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示