dp做题记录

树形 dp

  • P3177 [HAOI2015] 树上染色

    初看此题时,dp 状态很明显是两维,但是合并子树时答案难于统计,然后……就不会了qwq

    既然不通,考虑改变 dp 数组的含义,记 \(dp_{i,j}\) 表示当前 \(i\) 的子树中将 \(j\) 个点染黑对总答案的贡献

    但是这样直接计算两点距离就变得更难了,考虑两点的路径统计,将统计相同颜色点两两之间的距离转化为统计每个边被计数的次数。于是我们每次进行转移时只需要考虑 \(i\) 到它的儿子 \(j\) 的边 \(e_{i,j}\) 对总答案的贡献,于是有 dp 方程:

    \[dp_{u,j}=dp_{u,j-k}+dp_{v,k}+e_{u,v}k(m-k)+e_{u,v}(siz_v-k)(n-m-siz_v+k) \]

    其中 \(n\) 为点的个数,\(m\) 为总的可以允许染成黑色点的个数,\(e_{u,v}\) 表示 \(u\)\(v\) 边的权值,\(siz_u\) 表示以 \(u\) 为根的子树的大小,\(j\)\(k\) 均为枚举的染黑点的个数。

    但是这样转移很明显是 \(O(nm^2)\) 的,于是我们在枚举每一个 \(m\) 时,给予 \(m\) 一个上下界限制,最大可能地去优化时间复杂度,于是有了 \(m\) 的限制:\(m\in[\max(0,j-siz_u+isz_v),\min(j,siz_v)]\)

    可以证明,这样的时间复杂度是接近 \(O(nm)\) 的。

    代码

  • P7310 [COCI2018-2019#2] Deblo

    注意到位运算每一位都是独立的,考虑将权值的每一位拆开,单独考虑每一位对答案的贡献。

    先枚举每一位,这样原树就变成了一颗只有 \(0\)\(1\) 的树。很明显只有当路径上的 \(1\) 的个数为奇数时,这条路径才会对答案产生贡献。

    \(dp_{u,0}\) 表示路径的一个端点为 \(u\),另一个端点在 \(u\) 的子树,路径上的 \(1\) 的个数为偶数时,这样的路径的条数。同理 \(dp_{u,1}\)\(1\) 的个数为奇数。

    转移时进行分类讨论:

    • 若当前的节点 \(u\)\(w\) 位是 \(1\),那么对于其每一个子节点 \(v\),有 \(dp_{u,0}+=dp_{v,1},dp_{u,1}+=dp_{v,0}\)
    • 若当前的节点 \(u\)\(w\) 位是 \(0\),那么对于其每一个子节点 \(v\),有 \(dp_{u,0}+=dp_{v,0},dp_{u,1}+=dp_{v,1}\)

    考虑如何计算答案,显然对于一条路径只有两种情况:

    • \(lca_{a,b}\) 不为 \(a\) 或者 \(b\),有 \(ans+=dp_{u,1}\times dp_{v,0}+dp_{u,0}\times dp_{v,1}\),其中 \(v\)\(u\) 的子节点。
    • \(lca_{a,b}\)\(a\) 或者 \(b\) 其中一个,有 \(ans+=dp_{u,1}\)

    时间复杂度 \(O(n\log V)\),其中 \(V\) 为值域。

posted @ 2024-08-27 11:05  dayz_break  阅读(24)  评论(2)    收藏  举报