树形 $dp$ .
设 $f(i,j)$ 表示将子树 $i$ 全部点亮,下一次点亮点 $j$ 的最小花费.这样的话,状态数是 $O(n^2)$ 的.
注意到点亮子树 $i$ 后,下一次要么点亮 $i$ 的某个祖先,要么点亮 $i$ 的某个祖先的另外一侧的儿子.树是完全二叉树,所以可以直接用深度表示,树深是 $O(\log n)$ 的,再通过位运算得到节点标号.
设 $f(i,j)$ 表示点亮子树 $i$ 后,下一次点亮 $i$ 的第 $j$ 级祖先的最小花费, $g(i,j)$ 表示点亮子树 $i$ 后,下一次点亮 $i$ 的第 $j$ 级祖先的另一个儿子的最小花费.这样状态数是 $O(n\log n)$ 的.
默认以 $1$ 为根, $dp$ 求出 $f,g$ 的值.然后枚举第一个点亮的点 $x$ ,先点亮子树 $x$ ,跳到 $fa_x$ ,再点亮 $fa_x$ 的另一侧子树,再跳到 $fa_{fa_x}$ ,点亮 $fa_{fa_x}$ 的另一颗子树…需要跳 $O(\log n)$ 次.
时间复杂度 $O(n\log n)$ .
1 |
|