【题解】Solution Set - NOIP2024集训Day28 树形 dp

【题解】Solution Set - NOIP2024集训Day28 树形 dp

https://www.becoder.com.cn/contest/5521


「HDU4661」Message Passing

一个合法方案的构成一定是:

  1. 先将所有的信息整合到一个点上;
  2. 然后从这个点扩展开。

「BZOJ3935」Rbtree


「ARC101E」Ribbons on Tree


「AGC034E」Complete Compress

假如我们现在已经知道了最后会合的那个点 \(x\)

以她为根,根节点 \(dep_x=0\)。如果我们能找到一种合适的匹配方式,那么答案就应该是 \(\sum dep_i/2\),否则应该无解。

现在就变成了一个判断问题。考虑 dp。

\(f_{i}\):在 \(i\) 这棵子树内,尽可能配对完(配对的都到 \(i\))之后剩下最少的到 \(i\) 的距离之和。

\(h_i\):在 \(i\) 这棵子树内,棋子个数。

如果 \(f_x=0\) 那么就可以更新答案。


一个子儿子的子树需要上移的次数为 \(g_v=f_v+h_v\)

我们记录一个点的所有儿子的 \(g\) 之和 \(sum\)\(g\) 的最大值 \(mx\)

如果 \(mx\times2>sum\),就是说必须要向上有 \(mx-(sum-mx)\)

否则就可以 \(f_u=sum\bmod 2\)

但是:WA 90pts


问题在于这个 dp 其实是带有了一定的贪心,相当于我们是算了每个子树内都要尽量匹配,但是有这种情况:

image

对于 \(4,5,6\) 节点的 \(f\) 分别为 \(2,2,4\)

对于 \(1\) 点显然是合法的,但是这个做法让 \(4,5\) 节点在 \(2\) 就合并了,也就是说 \(f_2=0\),导致 \(6\) 上的不能到 \(1\)


其实我们需要的并不是每个儿子都最优,而需要的是每个儿子尽量的均衡。

\(f\) 记录了每个子树需要的最小值,我们不妨记录需要的最大值 \(g\),也即所有点到当前根的距离之和。

在这个范围内的,每隔两个值都能取到其中一个。

所以上面求的 \(sum\) 实际上是下界,但是我们需要的其实是上界,然后再按上面的做法做就行。


「COCI 2014.10」Kamp

答案就是所有经过的边的并集的权值和 \(\times~ 2~-\) 距离当前点最远的点。

有点恶心的换根 dp。bf

需要记录次长链,因为不要求严格,所以没必要记录最长链是指向哪个儿子,直接判值相等就行。


「SCOI2015」小凸玩密室

做过。

一种状态的定义:

\(f_{u,x}\): 走完 \(u\) 的子树,结束在 \(x\)\(u\) 子树中的叶节点)。

这样可以 \(O(n^3)\) 解决。

但实际上不管最终在那个点结束,都会跳到 \(u\) 的祖先或祖先的兄弟,所以换一种定义:

\(f_{u,x}\): 走完 \(u\) 的子树,结束在 \(u\) 的第 \(x\) 级祖先的兄弟。

\(g_{u,x}\): 走完 \(u\) 的子树,结束在 \(u\) 的第 \(x\) 级祖先。


注意到对于一条路径我们把其拆分开算的(只要终点一样。


「AGC008F」Black Radius

posted @ 2024-09-12 14:55  CloudWings  阅读(23)  评论(0编辑  收藏  举报