NFLS Dp 12.14

来源于 12.14 dp 训练。

如果没自己做出来会打星号。

暂时还没有补完。——last update 2024.1.3

简单 dp

我也不知道什么标题。

[AGC034E] Complete Compress

https://www.luogu.com.cn/problem/AT_agc034_e

枚举根 $r$。记 $x$ 为 $r$ 的儿子。$d_x$ 为所有有标记的点到 $x$ 的距离,记 $sum=\sum d_x$。如果 $\exists x,2d_x\le sum$,则能全部消掉,否则消不掉。

观察到如果一个子树内消消到的距离最小值为 $g_x$,最大值也就是不消的距离和为 $f_x$。则 $g_x,f_x$ 奇偶性相同且对于奇偶性相同的在 $[g_x,f_x]$ 的距离都可以构造出来。于是我们想求出 $g_x$。

考虑从儿子中转移。我们贪心的想使得 $f_x$ 最大的先在子树内消一下,然后再和其他的儿子一起消。如果 $\exists x,g_x+siz_x\le sum-(f_x+sum)$,则 $g_r=f_r\bmod 2$,否则 $g_r=g_x+siz_x-sum+f_x+suz_x$。

如果为 $r$ 根合法当且仅当 $g_r=0$。复杂度 $O(n^2)$。

*CF908G New Year and Original Order

记数的位数为 $n$。

先讲一下自己想到的 $O(10^2n^2)$ 做法。

link 一样,将排序以后的数看成若干个 $111\dots 111$ 构成的后缀。

而在本题中,记 $f(k,i)$ 表示 $k$ 在所有数中恰好出现在第 $i$ 位的个数,答案为 $\sum k\sum _{i=1}^n 10^{i-1}f(k,i)$。而恰好不好算,考虑一个很经典的竖着算转横着算,计算 $f(k,i)$ 表示 $\ge k$ 的数在所有数中恰好出现在 $i$ 次的个数,答案为 $\sum k \sum _{i=1}^n f(k,i)\times w(i)$,其中 $w_i=111\dots 1$,总共 $i$ 个 $1$。前面那个东西再记个是否顶到上界。应该好 dp。

然后看题解的 $O(10^2n)$ 的算贡献做法感觉很高妙啊。

考虑对每一个数 $d$ 算贡献。记 $f(i,0/1)$ 表示算到第 $i$ 位,数 $d$ 对答案的贡献。$g(i,0/1)$ 表示算到第 $i$ 位,在第 $i$ 位放 $d$ 对答案的贡献。后面的 $0/1$ 表示是否顶到上界。

然后枚举 $i-1$ 位的数位 $x$。有转移:

  • $x<d$,那么 $f(i,0/1)\gets f(i-1,0/1),g(i,0/1)\gets g(i-1,0/1)$。
  • $x=d$,那么 $f(i,0/1)\gets 10f(i-1,0/1)+g(i-1,0/1),g(i,0)\gets g(i-1,0/1)$。
  • $x>d$,那么 $f(i,0/1)\gets 10f(i-1,0/1),g(i-1,0/1)\gets 10g(i-1,0/1)$。

分别就是看加入一个数对前面是否左移。

*CTT2017 某位歌姬的故事

https://www.luogu.com.cn/problem/P4229

先把区间离散化,这样只有 $2q$ 个点。

区间 $\max$ 为一个数,等价于区间所有数都小于等于 $\max$,且存在一个数等于 $\max$。

先对每个操作做区间覆盖,则每个点有一个取值上限 $h_i$。

对于每个点,只可能对 $\max=h_i$ 的区间有贡献。考虑把对于每个值把这样的区间拿出来。问题转化为了一个序列,染黑(存在 $h_i$)或者染白,有许多区间限制,每个区间中至少要有一个染黑的,求方案数。

先转化为所有都染白,然后有些点染黑的方案数。令 $f_i$ 表示钦定 $i$ 为结尾且染黑的方案数,再维护一个左端点表示可以转移的区间,再前缀和搞搞就好了。

复杂度 $O(q\log q)$。

加强版:https://www.luogu.com.cn/problem/AT_abc262_h。

笛卡尔树 dp

结合笛卡尔树做 dp。

BZOJ4380 [POI2015] Myjnie

https://www.luogu.com.cn/problem/P3592

观察到只有 $m$ 个有用的取值,先对 $c_i$ 离散化。

考虑区间 dp。令 $f_{l,r,k}$ 表示区间 ${l,r}$,最小值为 $k$ 的价值最大值。

转移枚举最小值所在的位置,算贡献预处理后缀和和 dp 数组的后缀最大值。

复杂度 $O(n^3m)$,有 $1/6$ 的区间 dp 常数,可以通过。

可以理解成把序列构成了一颗笛卡尔树,并且考虑在笛卡尔 树上计算贡献。

BZOJ2616 PERIODNI

https://www.luogu.com.cn/problem/P6453

观察到小的会影响大的而大的超出的部分不会影响小的,把序列做一个小根笛卡尔树。

令 $f_{i,j}$ 表示在子树 $i$ 中,已经选了 $j$ 个互不攻击的点的方案数。先把儿子的答案合并。

然后考虑在点 $i$ 的区间选,也就是宽为 $h_i-h_{fa_i}$,长为 $siz_i$ 的矩形选 $k$ 个点转移。对每个 $f_{i,j}$ 转移即可。

复杂度 $O(n^3)$。实现的好的话跑不满。

[AGC026D] Histogram Coloring

写了一个 $O(n^3)$ 的 dp。后面发现好像可以 $O(n)-O(n\log n)$。具体用小根笛卡尔树,然后计算一个矩形染色的方案数。讨论一些情况。

[JOI Open 2016] 摩天大楼

插入 dp。同 ZJOI 波浪。

考虑一个把所有元素按照从大到小的顺序放到排列中正确的位置 的过程。那么每次插入一个元素,其所在的连续段就是以其为根在笛卡尔树上的子树。

这么做最后的值域会很小,但是 dp 中存在加减用到的值域会很大。考虑将 dp 差分,这样每次都是加法。

细节比较多。

dp 套 dp

dp 套 dp 是给定一个 DP 问题 A,用另一个 dp 去计算一种可能的 A 的输入,使得 A 的 dp 结果为 $x$。

也就是外层的 dp 的状态是另一个 dp 的结果。

BZOJ3864 Hero meet devil

https://hydro.ac/d/bzoj/p/3864

经典 dp 套 dp。先考虑求 LCS 的 dp。设 $f_{i,j}$ 表示 $t$ 的前 $i$ 位和 $s$ 的前 $j$ 位的 LCS。

然后把这个第二维状态记录下来。设 $F_{i,S}$ 表示当前考虑 $t$ 的前 $i$ 位,$f_i$ 的状态是 $S$ 的方案数。

第二维状态看上去是 $|s|^{|s|}$ ,分析发现相邻两个数的值最多只会差 $0/1$,状态存其 dp 值的差分数组即可优化为 $2^{|s|}$。状态与状态之间转移预处理出来即可 $O(1)$ 转移。

dp 复杂度 $O(m2^n)$。