分段类 dp
一般用于统计方案数。
一般将状态设为 \(dp_{i,j}\),表示考虑了前 \(i\) 个数,共分为 \(j\) 段的方案数。
转移分 \(3\) 种情况:
- 新增块
- 在原有块中插入
- 合并块
具体需要结合题目分析。
P5999 [CEOI 2016] kangaroo
要求一个长度为 \(n\) 的排列 a,使得 \(\forall i,1<i<n\),满足 \(a_{i-1}<a_i<a_{i+1}\) 或 \(a_{i-1}<a_i<a_{i+1}\),且要求 \(a_1=s\),\(a_n=t\),求出可能的方案数。
发现区间 dp 不太好做,可以尝试分段来思考。
设 \(dp_{i,j}\) 表示前 \(i\) 个数,分 \(j\) 段的方案数。
\(i\) 从小到大考虑。
代入 \(3\) 种情况:
-
新增块,那么原有 \(j\) 个空位可以插入。但是不可以插入到 \(s\) 前面或 \(t\) 后面。形式化的,你可以插入 \(j-[i>s]-[i>t]\) 个空位去。若 \(i>s\),则 \(s\) 在 \(i\) 前插入了,\(t\) 亦然。转移式显然为 \(dp_{i,j}\gets dp_{i,j}+dp_{i-1,j-1}\times (j-[i>s]-[i>t])\)。
-
插入,仔细思考是不可能的,因为若当前在某个块中插入,则:
- 必然比左边的数大。
- 后面插入进来的数必然比它大。
- 若这个数的右边不再插入数,则当前操作为合并而并非插入。
可以结合合并思考。
-
合并,即将 \(j+1\) 个块合并成 \(j\) 个块。容易发现有 \(j\) 组相邻的块,且合并不受 \(s\),\(t\) 的干扰。转移式为 \(dp_{i,j}\gets dp_{i,j}+dp_{i-1,j+1}\times j\)。
特别的,若 \(i=s\) 或 \(i=t\),则当前这个值要么在最前或最后新建一个块,要么直接合并。
即 \(dp_{i,j}\gets dp_{i,j}+dp{i-1,j}+dp{i-1,j-1}\)。
答案在 \(dp_{n,1}\) 中。

浙公网安备 33010602011771号