问题:给出一个长度为 n ( 1 ≤ n ≤ 1 0 6 ) n \quad(1 \leq n \leq 10^{6}) n(1≤n≤106)的字符串,你需要求出该字符串有多少个不同的子序列。
子序列的问题乍一看和字串的问题很相似,可能要用到后缀数组等高级数据结构。仔细想想其实没有必要的,一个 O ( n ) O(n) O(n)的 d p dp dp就可以解决。
对于给出的字符串 A [ 1 ] , A [ 2 ] , . . . A [ n ] A[1],A[2],...A[n] A[1],A[2],...A[n],我们用 d p [ i ] dp[i] dp[i]表示以字符 A [ i ] A[i] A[i]结尾的子序列的数量,显然这个 d p dp dp的关键点在于如何不重不漏的计算答案(其实这也是很多 d p dp dp方程需要想的问题)。
在考虑 d p [ i ] dp[i] dp[i]时,显然我们要尝试把字符 A [ i ] A[i] A[i]接到前面已经构成的子序列后面,那是不是 d p [ i ] = ∑ j = 0 i − 1 d p [ j ] dp[i]=\sum_{j=0}^{i-1}dp[j] dp[i]=∑j=0i−1dp[j]?不完全正确。
我们发现 当存在一个字符 A [ j ] = A [ i ] ( 1 ≤ j ≤ i − 1 ) A[j]=A[i]\quad (1\leq j \leq i-1) A[j]=A[i](1≤j≤i−1)时,将 A [ i ] A[i] A[i]接到 j j j以前的子序列构成的字符串和将 A [ j ] A[j] A[j]接到 j j j以前的子序列构成的字符串相同。
因此我们可以记录每一个字符出现的上一个位置,在转移过程中,只计算到这个位置就可以了,当然我们要初始化 d p [ 0 ] = 1 dp[0]=1 dp[0]=1。
记 A [ i ] A[i] A[i]出现的上一个位置是 l a s las las,即 A [ i ] = A [ l a s ] A[i]=A[las] A[i]=A[las]。开始 d p dp dp前所有的 l a s las las都是 0 0 0,表示这个字符上次出现的位置是 0 0 0。
那么 正确的 d p dp dp方程就是 d p [ i ] = ∑ j = l a s j = i − 1 d p [ j ] dp[i]=\sum_{j=las}^{j=i-1}dp[j] dp[i]=∑j=lasj=i−1dp[j]。
最终的答案: a n s = ∑ j = 1 j = n d p [ j ] ans=\sum_{j=1}^{j=n}dp[j] ans=∑j=1j=ndp[j]。