对求本质不同子序列个数的一点理解

stO https://www.cnblogs.com/ptno/p/16541669.html Orz

DP求本质不同子序列个数

求长度为 \(n\) 的序列 \(a_1,a_2,\dots,a_n\) 的本质不同子序列数。

Method 1

\(f_i\) 表示以 \(i\) 结尾 且之前没出现过 的子序列个数,\(las_v\) 表示 \(v\) 上一次出现的位置,则

\[f_i=\sum\limits_{j=las_{a_i}}^{i} f_j \]

前缀和优化即可 \(O(n)\) 完成。

Method 2

\(f_i\) 表示前 \(i\) 个数构成的本质不同子序列个数,\(las_v\) 表示 \(v\) 上一次出现的位置,如果 \(a_i\) 没有出现过,那么

\[f_i=2f_{i-1}+1 \]

上面 \(+1\)\(a_i\) 单独构成一个子序列。
否则 \(a_i\) 出现过,因此要减去重复统计的部分。

\[f_i=2f_{i-1}-f_{las_{a_i}-1} \]

Method 3:可矩阵优化

\(f_{i,j}\) 表示前 \(i\) 个数构成的以 \(j\) 结尾的本质不同子序列个数,转移为

\[f_{i,j}= \begin{cases} f_{i-1,j},s_i \neq j\\ \sum\limits_k f_{i-1,k}+1,s_i=j\\ \end{cases} \]

直接转移的复杂度为 \(O(n\left|\sigma\right|)\),矩阵实现为 \(O(n\left|\sigma\right|^3)\),显然对一般情况矩阵反而会造成负优化。

对于一些特殊的情况,例如转移矩阵周期性变化,就可以用矩阵加速。

一些理解

Version 1

强制选 \(a_n\),求本质不同子序列个数。

\(f_i\) 表示以 \(i\) 结尾 且之前没出现过 的子序列个数(Method 1)。

答案不是 \(f_n\),注意到我们的状态中含有 “之前没出现过” 这一限制,所以我们也要考虑之前出现过的状态,即前面以 \(a_n\) 结尾的状态。答案是

\[\sum\limits_{a_i=a_n}f_i \]

posted @ 2022-11-10 20:44  hzy1  阅读(1080)  评论(0编辑  收藏  举报