对求本质不同子序列个数的一点理解
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
\]