分段类 dp

一般用于统计方案数。

一般将状态设为 \(dp_{i,j}\),表示考虑了前 \(i\) 个数,共分为 \(j\) 段的方案数。

转移分 \(3\) 种情况:

  1. 新增块
  2. 在原有块中插入
  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\) 种情况:

  1. 新增块,那么原有 \(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])\)

  2. 插入,仔细思考是不可能的,因为若当前在某个块中插入,则:

    • 必然比左边的数大。
    • 后面插入进来的数必然比它大。
    • 若这个数的右边不再插入数,则当前操作为合并而并非插入。

    可以结合合并思考。

  3. 合并,即将 \(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}\) 中。

posted @ 2025-05-10 11:18  立花廿七  阅读(33)  评论(0)    收藏  举报