dp 学习练习选讲

括号序列

  1. 对于括号排列这种题目,一个合法的方案就是维护一个 (\(1\))\(-1\) 的一个前缀和数组,然后合法的充要条件就变为了这个前缀和数组的最小值为 \(0\) 且末尾为 \(0\)
  2. 按外层配对括号 \(\texttt{(...)(...)...(...)}\) 拆开
  3. 拆出第一对配对括号,剩下视作整体 \(\texttt{(...)...}\)
  4. 视作一个平面上的折线,进行容斥。

CF1781F

Bracket Insertion.

做法一:

对这个随时插入的序列用前缀和数组维护,我们发现我们不需要考虑末尾为 \(0\),只需要保证每个数都不小于 \(0\) 即可。
对于两种插入可能,假设在插入位置的前面的前缀和为 \(x\),则插入 () 就会有 \(x,x+1,x\),同理有 )(\(x,x-1,x\)

于是我们就可以把前缀和数组转化成一个可重集合,初始为 \(\{0\}\),每次操作就是等概率的在集合中抽出一个 \(x\)\(p\) 的概率在集合中放入 \(\{x+1,x\}\)\(1-p\) 的概率在集合中放入 \(\{x-1,x\}\),求最终所有元素非负的概率。

这时我们可以把概率转化为求出一个方案数:在进行 \(k\) 轮操作后等概率抽出一个 \(x\) 的概率是 \(\frac{1}{2k+1}\),而 \(p\) 也已知,每次相当于把 \(p\)\(1-p\)\(1\frac{1}{2k+1}\) 赋权给这个集合,我们要求的就变成了所有合法集合的权值积的和。

这个问题就可以考虑 dp。设 \(f(k,x)\) 表示初始集合数为 \(x\),在进行 \(k\) 次操作后所有合法集合的权值的和。则我们要求的就是 \(dp_{n,0}\)
思考转移,对于一个状态 \(f(n,x)\),我们有 \(p\) 的概率和 \(1-p\) 的概率的两种转移:

\[\sum_{i=0}^{n-1}\sum_{j=0}^{n-i-1} p\binom{n-1}{i}\binom{n-1-i}{j} · f(i,x) · f(j,x+1) · f(n-1-i-j,x) + \]

\[+ (1-p)\binom{n-1}{i}\binom{n-1-i}{j} · f(i,x) · f(j,x-1) · f(n-1-i-j,x) \]

\(\texttt{...(...)...}\) 三个位置继续放。

然后就成功有了 \(O(n^4)\) 的做法,但 \(n\le 500\)
我们发现两种情况中重合了大部分的项,剩下的 \(p\times f(j,x+1)+(1-p)\times f(j,x-1)\),就可以把 \(i\) 消掉,转移就只关于 \(j\),剩下的预处理即可,时间复杂度 \(O(n^3)\)

做法二:

我们发现我们可以根据方案 3,找到第一个匹配的括号,则剩下的就只有 2 个区域,于是我们就更快的得到了 \(O(n^3)\) 的转移方程:

\[f(n,x)=\sum_{k=0}^{n-1} \binom{n-1}{k}(p\times f(k,x+1)\times f(n-1-k,x)+(1-p)\times f(k,x-1)\times f(n-1-k,x)) \]

吊打做法一

CF629C

Famil Door and Brackets.
我自己只能手切这种题了菜完了
本来是可以考虑有多少个排列包含 \(s\),但是我们发现总共要填的数不超过 \(2000\),而 \(|s|\) 又非常大,所以考虑对两边分别考虑,我们考虑 dp 求出长度为 \(i\),前缀数组大小为 \(j\) 的字符串数量,然后对前面长度和前缀大小进行考虑即可。

当然的还有一些类括号序列的结构。

CF888F

Connecting Vertices.

首先断环成链,那么对于一个区间 \([i,j]\),由于它是一个联通块,,那么区间有如下这两种形式:
o0rauqlf

其中 type 1 是 \((i,j)\) 没有连边的情况,type 2 是 \((i,j)\) 连了边的情况。但由于这是一棵树,所以这个 type 2 连通块必然有个断点,用枚举断点来转移。type1 按方式 3 转移。
具体的,有 \(dp_{i,j,0/1}\) 表示当前连通块为 \([i,j]\)\(0/1\) 表示 \((i,j)\) 间是否有连边。

那么转移就比较简单了:

  1. 对于 type1,\(dp_{i,j,0}=\sum_{k=i}^j dp_{i,k,1}\times (dp_{k,j,0}+dp_{k,j,1})\)
  2. 对于 type2,\(dp_{i,j,1}=\sum_{k=i}^{j-1} (dp_{i,k,0}+dp_{i,k,1})\times (dp_{k+1,j,1}+dp_{k+1,j,1})\)
posted @ 2026-08-20 00:01  OIerYang  阅读(6)  评论(0)    收藏  举报