abc391 题解

切了 A~F,但是涨不了多少分,不开心。


D - Gravity:

考虑维护每一排的元素什么时候被消除,我们还需要维护每一个滑块什么时候到底,递推维护即可。

E - Hierarchical Majority Vote:

爆搜即可。

F - K-th Largest Triplet:

\(a,b,c\) 从小到大排序,在优先队列(或者说是 set)里维护 \((i,j,k)\),转移可以转移到 \((i+1,j,k)\)\((i,j+1,k)\)\((i,j,k+1)\),转移 \(k\) 次即为第 \(k\) 大。

G - Many LCS:

看到 \(n,m\) 都很小,考虑最暴力的 dp。

回顾一下 LCP 怎么求,设 \(f_{i,j}\) 为匹配到 \(T\) 的第 \(i\) 位和 \(S\) 的第 \(j\) 位的最长公共子序列,转移式为:

\[\begin{gathered} {f_{0,0}=f_{1,0}=f_{0,1}=0}\\ {f_{i,j}\gets f_{i-1,j}}\\ f_{i,j}\gets f_{i,j-1}\\ \text{if}\ T[i] = S[j]\ \text{then}\ f_{i,j}\gets f_{i-1,j-1}+1 \end{gathered} \]

那么答案就是 \(f_{m,n}\)

我们可以在记方案数的 dp 状态里加上 \(f\),我们设 \(g_{i,f}\) 表示匹配到 \(T\) 的第 \(i\) 位时,数组 \(f_i\)\(f\) 的方案数。这个状态的转移是简单的,我们枚举 \(T\) 的第 \(i\) 位选什么,然后从 \(f_{i-1}\) 更新到 \(f_i\) 就可以转移了。

但是现在的问题就是我们无法在 dp 数组的状态里加入 \(f\) 这一维度,因为它实在是太大了。

我们仔细观察 \(f\) 的转移,我们可以发现它的一些性质。对于固定的 \(i\) 都有:

  • \(f_{i,0}=0\)
  • \(f_{i,j}\le f_{i,j+1}\le f_{i,j}+1\)

第二个性质让我们发现 \(f_i\) 相邻两项的差不超过 \(1\),这非常棒,这说明了 \(f\) 的差分数组只可能有 \(2^n\) 个,那么 \(f\) 也只可能有 \(2^n\) 个,所以我们可以在 \(g_{i,f}\) 中将 \(f\) 改存为 \(f\) 的差分数组,并将其压缩成一个二进制数,这样的复杂度就是对的了。时间复杂度:\(\mathcal{O}(nm2^n|\sum|)\)(当然我们也可以通过预处理做到 \(\mathcal{O}(m2^n|\sum|)\)),空间复杂度:\(\mathcal{O}(m2^n)\)

这种 dp 我们把它称为 dp 套 dp。

posted @ 2025-02-02 09:45  liruixiong0101  阅读(58)  评论(0编辑  收藏  举报