我不会动态规划

DP 杂题

【POI2015】洗车-Car washes-Myjnie

经典笛卡尔树上 DP,设 \(dp_{l, r, k}\) 表示区间 \([l, r]\) 最小值为 \(k\) 的总收益,枚举最小位置 \(p\),为了避免算重,只考虑经过 \(k\) 且包含于 \([l, r]\) 的区间。做一个后缀和后转移是显然的。输入方案需要保存 \([l, r, k]\) 的选择的最值,最值的位置,然后递归下去求解。

时间复杂度 \(O(n^3m)\),由于数据应该比较水,因此跑不满。

【USACO2018Jan-P】救生员Lifeguards

显然有 \(nk^2\) 的 DP:将完全被包含的区间去掉后,将所有区间按 \(l\) 排序,则 \(r\) 也是不降的。设 \(dp_{i, j}\) 表示考虑到第 \(i\) 个的区间,目前删去了 \(j\) 个区间的最大并集,由于上一个位置 \(i - p \leq k\),因此 \(nk^2\)(据说还能过

优化也比较显然,\(dp_{i, j} = \max(dp_{p, j - (i - p - 1)}+r_i - \max(l_i, r_j))\),把第二个 \(\max\) 拆开用两个单调队列维护就行。

【POI2011】差值 Difference

枚举最大最小字符 \(a,b\),则只需要把 \(a,b\) 所有出现位置拉出来跑最大子段和。时间复杂度 \(O(|\sum|n)\)。但要求出现至少一个 \(-1\),可以求一个前缀和然后单调队列,但可以直接先初始化 \(s = -1\),不累计第一个 \(-1\) 的答案,每次若 \(s < 0\) 则令 \(s = -1\)。就可以保证正确性了。

【HNOI2007】梦幻岛宝珠

经典二进制位DP,对每个 \(w\) 分解成 \(a \times 2^b\) 后,每个 \(b\) 做一个 01背包,然后从低位到高位 DP:设 \(f_{i, j}\) 表示二进制 \(i\) 位,目前第 \(i\) 位是 \(j\) 的方案,枚举第 \(i\) 位有 \(k \times 2^i\) 的背包,则 \(dp_{i, j} = \max(dp_{i - 1, (j - k)\times 2+[s_{i - 1} = 1]}+f_{i, j})\),其中 \(s[i]\) 表示第 \(s\) 二进制 \(i\) 位是否为 1。答案就是 \(dp_{d, 1}\)\(d\)\(s\) 最高位 1。

[POI2007]ODW-Weights

由于物品之间互为倍数关系,因此不同的物品大小为 \(\log V\) 级别,且最后选择的物品一定是从小到大依次选择。

直接贪心需要考虑物品放入背包后是否会影响到体积更大的物品,于是可以预先将每个背包按照 \(\{v_i\}\) 的大小依次分组,也就是将背包 \(\{v_i \}\) 进制拆分,依次对每个背包考虑,若存在 \(i\) 位为 1 则直接选择,否则需要向高位借 1 做减法。由于背包之间互不影响,因此可以预先将所有背包的值相加,这样就只用考虑一个数了。

[POI2012]SZA-Cloakroom

物品按照 \(a\) 排序,设 \(dp_{i}\) 表示满足 \(\sum c_i = k\) 的集合中,\(\min(b_i)\) 最大的是多少,将询问离线扫一遍即可。

【BZOJ2031】剪枝

若两个叶子之间不相邻,则进行若干次操作后它们也不会相邻,最后存在的相邻叶子一定是初始相邻叶子路径之间(除 lca)的两个点,两个点的 lca 是两个叶子的 lca。由于 dfs 序的长度为线性,因此直接对相邻叶子进行 dp:设 \(dp_x\) 表示目前最后一个叶子是 \(x\) 的最大收益,转移从上一个叶子到 lca 的点转移到当前叶子到 lca 的点:\(dp_x = \max(dp_y- \max(h_x, h_y)) +w_x\),其中 \(h_x\) 表示 \(x\) 到 lca 上的最大点权。

暴力提取路径上点,\(h_x, h_y\) 显然都有单调性,预处理一些信息后直接双指针 \(O(n)\)

【AGC007E】Shik and Travel

二分答案 \(lim\)。设 \(dp_{x, l, r}\) 表示考虑 \(x\) 子树内的所有叶子的经过顺序,目前 \(x\) 距离第一个叶子为 \(l\),最后一个叶子为 \(r\) 的最小花费,转移:\(dp_{x, l, r} = \min_{p}\min_{q}[p+ q \leq lim] (dp_{lc, l, p}+dp_{rc, q, r}+p+q)\)。左右儿子可以交换。

然后是经典优化:若两个状态 \((l_1, r_1), (l_2, r_2)\) 满足 \(l_1 \leq l_2, r_1 \leq r_2\) 显然 \((l_2, r_2)\) 没用,因此所有状态按照 \(l\) 排序后,\(r\) 是单降的。在转移中固定 \(lc, l, p\),当 \(q\) 越来越大时,\(r\) 越来越小,因此只需要保留 最后一个 \(q\) 满足 \(p+q \leq lim\) 的点,可以双指针。得到 \(x\) 的所有状态后再保留合法状态即可。

若一个有 \(x\) 个状态的点和 一个有 \(y\) 个状态的点合并,会得到 \(2 \min(x, y)\) 个状态,类比启发式合并的复杂度,因此总状态是 \(O(n\log n)\) 级别。

[POI2014]MRO-Ant colony

分别固定给定边的两个端点为跟,由于 \(\left\lfloor\frac{\frac n a}b\right\rfloor = \left\lfloor \dfrac {n}{ab}\right\rfloor\),设 \(f_u\) 表示 \(u\) 到根的 \((deg_u - 1)\) 之和。计算有多少个 \(m_i\) 满足 \(\left\lfloor\dfrac{m_i}{f_u}\right\rfloor = k\), 可以直接排序后二分。

【CEOI2017】Chase

对于一条路径上的一个点 \(u\) 而言,要获得 \(a_u\) 的收益则 \(u\) 的上一个点必须选择,同时一个点被选择可以得到其邻域的收益。设 \(f_{u, 0 / 1}\) 表示 \(u\)\(u\) 子树的一条路径上 \(u\) 是否选择的最大值,\(g_{u, 0 / 1}\) 表示 \(u\) 子树中一个点到 \(u\) 的最大值,设 \(w\)\(u\) 子树 \(a\) 之和,则 \(f_{u, 0} = \max(f_{v ,0}, f_{ v, 1})\)\(f_{u, 1} = \max(f_{v, 0}, f_{v, 1}+w)\)\(g_{u, 0} = \max(g_{v, 0}, g_{v, 1}), g_{u, 1} = \max(g_{v, 0}, g_{v, 1}) + w - a_v + a_{fa}\)。然后枚举 lca 将 \(f, g\) 拼起来即可。

CF1097G Vladislav and a Great Legend

\(k\) 次幂转斯特林数,于是只要计算 \(f_k\) 表示在所有点集形成的虚树中选择 \(k\) 个点的方案。枚举点集的 lca 为 \(x\),设 \(dp_{x, i}\) 表示 \(x\) 为根的子树选择 \(i\) 条边的方案(保证点集不能为空),若 \(x\) 儿子 \(y\) 选择则 \(f_{x, i + j} \leftarrow f_{x, i} \times f_{y, j}, f_{x,i+j+1} \leftarrow f_{x, i} \times f_{y, j}\),同时累计答案 \(ans_{i+j} \leftarrow f_{x, i} \times f_{y, j}, ans_{i+j+1} \leftarrow f_{x, i} \times f_{y, j}\)。若 \(x\) 不选则预先将 \((x, y)\) 的贡献累加, \(f_{x, i} \leftarrow f_{y, i}, f_{x, i} \leftarrow f_{y, i - 1}\)\(O(n^2)\)

[CERC2017]Embedding Enumeration

显然每个点度数 \(\leq 3\),设 \(dp_u\) 表示放置 \(u\) 为根的子树,且 \(u\) 的左边不能方的方案。转移大概是分 \(son_u = 0, son_u = 1, son_u = 2\) 然后 \(u\) 子树是否是一条链,若不是一条完整的链则找到第一个 \(son_u = 2\) 的点 \(v\) 继续分讨。

勾八才写。

CF1088E Ehab and a component choosing problem

喂,110 吗,这里有人搞诈骗。诈骗题。

显然最大值当 \(k = 1\),且选择的是最大连通块。但是要最大化 \(k\)。则一定是选择若干个不相交的最大连通块。只用选出一个连通块后将其权值设为 0 即可。

CF582E Boolean Function

不同的函数只有 \(2^4\) 种可能,直接对每种函数值状压。建出表达式树,叶子节点都是变量,设 \(f_{x, s}\) 表示 \(x\) 为根,\(s\) 的第 \(i\) 位为 1 当且仅当 \(A, B, C, D\) 分别取第 \(i\) 种函数值时为 1。对于非叶子节点直接 FWT_or, FWT_and 一下就好。\(O(16 \times 2^{16} \times |s|)\)

【APIO2014】连珠线

容易发现蓝线只有两种情况:形成一条长度为 2 的链或者 \(u\) 的两个不同儿子上。若直接设 \(dp_{u, 0 / 1}\) 表示 \(u\) 子树,且 \(u\) 是否是第 1 类链的中央,直接转移是错误的,因为题目要求用红线连接的一端是新的。如下图:

(luogu.com.cn)

显然根的两个儿子之间不能通过红边再和 1 连蓝边得到。问题在于我们固定了根是 1。考虑题目的生成方式,初始为 1 个点,然后不断和新点连红色边,则只会出现链一种蓝色边。因此可以通过换根保证只存在链。

\(f_{u, 0} = \sum\limits_v \max(f_{v, 0}, f_{v, 1}+w)\)\(f_{u, 1} = \sum\limits_{v}f_{v, 0}+w +(f_{u, 0} - \max(f_{v, 0}, f_{v, 1}+w))\)

显然保存一下 \(\max(f_{v, 0}, f_{v, 1}+w)\) 的最大次大就可以换根了。

CF908G New Year and Original Order

答案只和每个数位的出现次数有关,而每个按照顺序排列的数都可以写成若干个 \(11\dots1\) 相加的形式。例如 \(114 = 111+1+1+1+1,111445 = 111111+111+111+111+1\)。总结规律:对于一个 \(0 \leq i \leq 9\),若 \(\geq i\) 的数出现了 \(k\) 次,则贡献即是 \(k\)\(11\dots1\)。然后随便数位 dp 一下就好了。

【HAOI2015】数字串拆分

\(m \leq 5\),则 \(f(S)\) 可以通过矩阵快速幂计算,初始向量为 \(\begin{bmatrix} f_{0} \\ f_{-1} \\ f_{-2} \\ \vdots \\ f_{-m+1} \end{bmatrix}\) 转移 \(n\) 次的 \(a[0][0]\) 就是 \(f_n\)。再考虑 \(g\),发现其实就是将字符串 \(str\) 拆分成若干位后,每个矩阵的 \(c\) 的幂相乘。因此设 \(dp_i\) 表示考虑前 \(i\) 个字符的矩阵,则 \(dp_{i} = \sum\limits_{j < i}dp_{j} \times trs[j+1, i]\),其中 \(trs[i, j]\) 表示原串第 \(i\) 个字符到 \(j\) 个字符的矩阵,预处理一些即可 \(O(|\sum|nm^3+n^2m^3)\)

【SDOI2017】序列计数

显然素数条件没什么用。容斥一下,用所有的方案减去不存在素数的方案。做循环卷积快速幂即可。\(O(m+p^2\log n)\)

CF1264C Beautiful Mirrors with queries

按照检查点分段,设 \(f_i\) 表示距离检查点为 \(i\) 出发走到终点的期望,每一段加起来就是答案。\(f_i =1+p_if_{i+1}+(1 - p_i)f_0\),用待定系数法倒推 \(f_0\) 解一次方程即可得到 \(f_0\),多次修改可以用线段树维护一次函数的复合,set 找前驱后继。

CF865C Gotta Go Fast

\(f_{i ,j}\) 表示第 \(i\) 个任务,目前经过 \(j\) 时到达目标的期望时间。\(f_{i, j} = (f_{i+1,j+a_i}+a_i) \times p_i + (f_{i+1, j+b_i}+b_i) \times (1 - p_i)\),还可以直接重开,期望为 \(f_{0, 0}\)。发现根本不能转移。于是将 \(f_{0, 0}\) 看做一个常量 \(v\),最后 dp 完后判断 \(f_{0, 0}\)\(v\) 的大小。发现有单调性,于是可以二分 \(v\)

CF913F Strongly Connected Tournament

由于竞赛图缩点后是一条链,套路地枚举没有出度的强联通分量进行转移。先预处理 \(f_n\) 表示 \(n\) 个点的竞赛图为 SCC 的概率,再容斥设 $g_{i ,j} $ 表示 \(i\) 个点的竞赛图,目前没有出度的集合大小为 \(j\) 的概率,每次加入一个 \(i+1\),考虑它是否加入没有出度的点,则 \(g_{i, j} = g_{i - 1, j} \times (1 - p)^{j} +g_{i - 1, j - 1} \times p^{i - j}\) ,则 \(f_n = 1 - \sum\limits_{i < n}f_i g_{n, i}\)。 设 \(dp_n\) 表示给 \(n\) 个没有定向的竞赛图定向的方案,将没有出度的点分隔开后,剩下的点已经被定向了,于是还需要设一个 \(h_{i}\) 表示给 \(n\) 个已经定向的竞赛图定向的方案,则 \(dp_{n}= \dfrac{\dbinom n 2+\sum\limits_{i < n}g_{n, i}f_i(dp_i+h_{n - i})}{1 - f_n}\)\(h_n = dp_nf_n + \sum\limits_{i < n}g_{n, i}f_i(dp_i+h_{n - i})\),同时转移 \(dp, h\) 即可。

同时总结一下竞赛图的一些性质吧:

  • 竞赛图一定有 Hamilton 路。
  • 竞赛图的一个 SCC,设其长度为 \(n(n>1)\),则其长度为 \(2, 3, \dots, n\) 的 Hamilton 回路存在。
  • 若要确定竞赛图缩点后没有出度的点的集合,将其入度从大到小排序后,所有不在末尾点的入度都比在的小,找到最后一个满足其入度前缀和 \(s = i(n - i)+\dbinom i 2\)\(s\),则前 \(i\) 个点就是答案。

[APIO2013] 机器人

对每个 \((i, j)\) 记搜预处理其从上下左右出发最后停下来的点(注意判环)由于 \([l, k]\)\([k+1,r]\) 机器人合并得到 \([l,r]\) 很难不想到区间 DP,同时,由于每个机器人的状态是独立的,于是设 \(dp_{l, r, x, y}\) 表示编号为 \([l, r]\) 的机器人在 \((x, y)\) 的最小代价,转移类似斯坦纳树,\(dp_{l, r,x,y} +1\rightarrow dp_{l, r, reach(x, y, 0 / 1 / 2 / 3 )}\),或 \(dp_{l ,r, x, y} = \min_{l \leq k < r}dp_{l, k, x, y}+dp_{k+1,r,x,y}\)

[JLOI2016] 字符串覆盖

分开考虑最大最小。

  • 最大:由于 \(n \leq 4\),先 \(n!\) 全排列一下每个字符串的出现位置,此时还不能直接贪心,因为后一个字符串与前一个字符串相交或者不相交都有可能成为最优的,于是再 \(2^{n - 1}\) 枚举是否相交,于是既可以贪心了,维护当前匹配右端点位置 \(p\),若钦定相交则找到 \(\leq p\) 的最后一个左端点,否则 \(>p\) 的一个左断点。
  • 最小:先去掉完全相交的字符串,设 \(dp_{S, i}\) 表示已添加字符集合为 \(S\),目前右端点为 \(i\) 的最短,转移显然,可以把 \(\max(l_i, r_j+1)\) 拆开,然后随便维护一下就好。(但是最大值也能这样做的说

CF845F Guards In The Storehouse

由于 \(\min(n, m) \leq \sqrt{250} = 15\),考虑轮廓线 dp。若 \(n > m\) 则交换 \(n, m\) 和矩阵,设 \(dp_{i, S, p = 0 / 1, q = 0 / 1}\) 表示当前考虑到第 \(i\) 行,目前有竖着扫过来的 guard 的集合为 \(S\),当前方格是否被扫到,目前是否有没被覆盖的格子的方案。

若当前为障碍则转移到 \(dp_{i, S / (1 <<i), 0, 0 / 1}\)。否则当且仅当 \(S\)\(i\) 位为 0 且 \(p = 0\) 没有被覆盖,若 \(q = 0\) 则可以转移到 \(q = 1\),否则只能强制放。

注意处理完一行后将 \(p\) 置为 0。

【BZOJ5210】最大连通子块和

套路动态 DP:有 \(f_x = a_x+\sum\limits_{y}\max(0, f_y),g_y = \max(f_x, \max_{y}g_y)\),设 \(lf_x= a_x+\sum\limits_{y \in lson_x}\max(0, f_y)\)\(lg_x = \max(\max_{y\in lson_x}g_y, lf_x)\),单独考虑重儿子有:\(f_x = \max(0, f_{son_x})+lf_x, g_x = \max(g_{son_x},lg_x, lf_x+f_{son_x})\),写成矩阵:
\(\begin{bmatrix} 0 \ \ -\infty \ \ \ lf_x \\ lf_x \ \ \ 0 \ \ \ lg_x \\ -\infty -\infty \ \ \ 0 \end{bmatrix}\times \begin{bmatrix} f_y \\ g_y \\ 0\end{bmatrix}\)

在对轻儿子进行更新时,\(lf_x\) 可以直接更新,\(lg_x\) 需要用一个可删堆维护所有的 \(g_y\)\(lf_x\)可为什么就是过不去啊

【IOI2016】aliens

先把矩阵变成一个上三角,则能把 \((x, y)(x \leq y)\) 覆盖的矩形满足 \(l \leq x \leq y \leq r\),将所有被完全覆盖的点去掉后,剩下的点满足 \(x_1 < x_2, y_1 <y_2\),于是设 \(dp_n\) 表示覆盖完前 \(n\) 个点的矩形最小覆盖数,则 \(dp_i = \min(dp_j+(y_i - x_{j+1}+1)^2) - (\max(0, y_j - x_{j+1}+1))^2\),拆开后斜率优化,由于选择矩形个数 \(k\) 具有凸性,外层再套一个 wqs 二分。\(O(n \log m^2)\)

【PA2014】团队Druzyny(BZOJ3711)

将最值和最值个数当作一个具有结合律的运算。显然可以 dp,若满足 \(\max_{k = j+1}^{i}l_k \leq i - j \leq \min_{k = j+1}^ir_k\)\(j\) 可以转移到 \(i\)。考虑怎么优化。

由于合法的 \(j\) 不是一个连续的区间,不能直接找到,于是考虑用 cdq 来优化 dp 转移。

预处理分治中心 \(mid\) 到左右的最大最小,设为 \(mx_j, mn_j, mx_i, mn_i\),则可以写成 \(\max(mx_i, mx_j) \leq i - j \leq \min(mn_i, mn_j)\),果断对四者的大小进行分讨,可以得到如下四种转移:

  • \(mx_i \geq mx_j, mn_i \leq mn_j\),则 \(mx_i \leq i - j \leq mn_i \to j \in [i - mn_i, i - mx_i]\),注意到 \(mn\)\(mx\) 具有单调性,因此合法的 \(j\) 必然是一段区间,用线段树维护一下。
  • \(mx_i < mx_j, mn_i \leq mn_j\),则 \(mx_j \leq i - j \leq mn_i\),若此时拆成 \(i\) 的限制则 \(i \in [mx_j+j, mn_i+j]\)\(mx_j+j\) 不具有单调性,不太好搞。若拆 \(j\)\(mx_j+j \leq i, j \geq i - mn_i\),此时 \(mx_j+j\) 具有单调性,也是一段区间向一个点转移。
  • 对于其他情况同理,可能会涉及到单点向区间转移的情况,可以直接标记永久化一下。

时间复杂度 \(O(n\log^2 n)\)

据说还可以将 \(\max l_i\) 建出笛卡尔树,那么下界就是一个常数,此时只用分两种情况讨论,但可能两段区间长度不平衡因此需要启发式分裂一下。

[POI2014]SUP-Supercomputer

勾八结论题,会结论就是个勾八题了。

结论:最优方案一定存在一个深度 \(d\),使得 \(\leq d\) 的能在 \(d\) 次操作完,\(\geq d+1\) 的点能每次操作 \(k\) 个点,答案为 \(d+\left\lceil\dfrac{s_{d+1}}k\right\rceil\),其中 \(s_d\) 是深度 \(\geq d\) 的点的个数。\(c\) 的答案是 \(\max{d+\left\lceil\dfrac{s_{d+1}}k\right\rceil}\)

证明:

最优性:若深度 \(j\) 不能在 \(j\) 步走完,一定存在 \(i\) 使得深度 \(i\) 能在 \(i\) 步走完(显然存在,因为 \(i = 1\) ),此时 \(i < j\) ,深度在 \([i+1,j]\) 的点一定需要大于 \(j - i\) 步才能走完,因此 \(\left\lceil\dfrac{s_{i+1}-s_{j+1}}k\right\rceil > j - i\),$s_{i+1}+ik\geq s_{j+1}+jk \rightarrow i+\left\lceil\dfrac{s_{i+1}}k\right\rceil\geq j+\left\lceil\dfrac{s_{j+1}}k\right\rceil $。

\(\geq j+1\) 的点不能每次都选 \(k\) 次,存在 \(i\) 使得 \(\geq i+1\) 的点能每次都选 \(k\) 次,则 \(i>j\),则 \([j+1,i]\) 的点

posted @ 2023-01-23 15:08  henrici3106  阅读(76)  评论(0编辑  收藏  举报