树形dp
时间复杂度:\(O(nd)\)
以前整理的比较笼统
首先,我做的时候设的是 \(f\) 表示向下 \(j\) 层, \(g\) 是上下一起
转移 \(f_{u,j}=f_{v,j-1}\)
但这显然不对
这是因为我没考虑清楚一些东西:
-
关键点与普通点的区别
-
覆盖会有一大部分是重叠的,别的点帮忙没考虑
先看第二个点
对于别的点帮忙,只需要考虑儿子对父亲的
为啥?
因为儿子对儿子的和父亲对儿子的很好处理,只需要在转移中不累加而是取 \(\min\)
那还有对祖先的呢,这样就不能单纯 -1 了吧
对,所以加一维 \(j\) 表示向上覆盖几层
对于儿子给父亲覆盖完了的点,父亲就不用覆盖了,这需要在状态里扣掉
于是设 \(g_{u,j}\) 表示 \(g\) 向下 \(j-1\) 层有没有被覆盖随便,\(j\) 层及以下全部被覆盖的最小花费
关于第一点,我们可以不覆盖普通点
转化一下,如果这个点覆盖的点全是普通点,那么这个点覆不覆盖也没啥影响,这题算的是花费,我们直接把他的花费刨除掉,就是 \(f_{u,0}=g_{u,0}=0\)
但是,他可以转移成 0,但如果要用它去覆盖其他点,他的花费是要算的,于是 \(f_{u,j}=val_u\) \(,j \leq d\)
想转移时要把所有情况都列出来
-
我覆盖我,我的儿子被我覆盖
-
我被我的儿子覆盖
万事俱备!江东纵火团!放箭转移!
\(f_{u,i}=\min(f_{u,i}+g_{v,i},g_{u,i+1}+f_{v,i+1})\)
注意这里其实 \(g\) 都是要取一个 \(\sum\),但转移时随着 \(f_{u,i}\) 的更新就相当于取了 \(\sum\)
所以,转移是要先更新 \(f\) 再更新 \(g\) 的
贪心思路看题解吧
设 \(f_{i,j,0/1}\) 表示以 \(i\) 为根出发走 \(j\) 步,不回/回到根结点的最小新结点数
\(f_{i,j,0}=\max(f_{i,j-t,0}+f_{v,t-2,1},f_{i,j-t,1}+f_{v,t-1,0})\)
\(f_{i,j,1}=\max(f_{i,j-t,1}+f_{v,t-2,1})\)
一个一个解释:
\(i\) 走到 \(v\),\(v\) 走,回到 \(v\),\(v\) 走到 \(i\),\(i\) 走
\(i\) 走,回到 \(i\),\(i\) 走到 \(v\),\(v\) 走
\(i\) 走,回到 \(i\),\(i\) 走到 \(v\),\(v\) 走,回到 \(i\)
一开始注意到这里累加贡献需要子树的每个点的颜色状态,有后效性
有后效性就把他放进状态里……
但这也不能状压啊
那就反过来,不算每个子树内的答案,而是算每个点对答案的贡献
发现每次节点所在的子树的根与节点是一个颜色时就会对答案有 1 的贡献
所以,状态为 \(f_{x,0,j,k}\) 这个点为 0/1 色,他向上有 j 次黑色合并,k 次白色合并
枚举每个子节点选白还是选黑
\(f_{u,0,j,k}=\sum \max(f_{v,0,j+1,k},f_{y,1,j,k})\)
\(f_{u,1,j,k}=\sum \max(f_{v,0,j,k},f_{y,1,j,k+1})\)
初始化:\(f_{u,0,j,k}=w[u] \times (j+1)\) , \(f_{u,1,j,k}=w[u] \times (k+1)\)

浙公网安备 33010602011771号