序列上的DP

trick

  1. 很多 01 串问题,都是固定 0 或者 1,移动另外一种,这样会方便考虑很多。

  2. 如果题目需要考虑当前位选还是不选时,你可以多记一位,也可以强制选,在向后转移的时候在考虑不选时的状态。

题目

P17337 【MX-X30-T3】宇宙分解 \(\checkmark\)

题目大意

给定 01 串,可任意次执行:若相邻为 01,可删除右边的 1,或将 01 交换为 10。求最终能得到多少种不同的 01 串,对 998244353 取模。
\(T \le 10^3\),所有测试 \(n\) 之和 \(\le 10^5\),所有串中 \(1\) 的个数总和 \(S \le 2\times 10^3\)

解题思路

解题思路

启示这道题的数据范围提示的很明显,复杂度是要 \(O(nS)\) 的。

固定 0,操作就相当于选择左移 1 或者删掉这个 1,由于当前第 \(i\) 位的取值依赖于 \(i-1\) 位的情况,所以考虑 DP。

定义 \(f_{i,j}\) 表示强制选第 \(i\) 个 1,它的左边有 \(j\) 个 0,那么转移就是:

  • \(i-1\)\(dp_{i,j}=\sum_{k=0}^j dp_{i-1,k}\)
  • 不选 \(i-1\),此时 \(i-1\) 在哪已经不重要了,贡献的序列都是相同的,所以直接加一即可。

这个很容易用前缀和优化,在加个滚动数组即可。

一个小提示,如果该序列前缀都是 1 的话,他们对答案没有任何贡献,不考虑。

启示: 很多这种 01 串问题,都是固定 0 或者 1,枚举移动另外一种,这样会方便考虑很多。还有一点,如果题目需要考虑当前位选还是不选时,你可以多记一位,也可以强制选,在向后转移的时候在考虑不选时的状态。

posted @ 2026-09-02 19:48  lcx_OIer  阅读(8)  评论(0)    收藏  举报