求本质不同的子序列数量

如何求 \(s\) 的本质不同的子序列数量?

设字符集大小为 \(siz\)


法一

\(f_i\) 表示前 \(i\) 个字符的答案

\[f_i= \begin{cases} f_{i-1}+f_{i-1}+1,s_i \text{第一次出现}\\ f_{i-1}+f_{i-1}-f_{x-1},s_i \text{上一次出现在}x \end{cases} \]

  • 考虑不选:\(f_{i-1}\)
  • 选:\(f_{i-1}-f_{x-1}\) ,避免算重

\(O(nsiz)\)

法二

\(f_{i,j}\) 表示前 \(i\) 个字符,以 \(j\) 结尾的答案

为了去重,要求若 \(s_i=j\) 则必须选 \(i\)

\[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(nsiz)\)

  • 此法可以矩乘优化

显然将对角线染上 1 ,再将第 \(s_i\) 列染上 1 即可

\(O(nsiz^3)\)反优化

法三

\(f_{i,j,k}\) 表示前 \(i\) 个字符,以 \(j\) 结尾,长度为 \(k\) 的答案

为了去重,要求若 \(s_i=j\) 则必须选 \(i\)

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

\(O(n^2siz)\)

posted @ 2020-12-19 16:41  苹果蓝17  阅读(417)  评论(0编辑  收藏  举报