动态规划——不重复子序列DP法
考虑一个基本模型:
给定一个字符串
S
S
S,请问
S
S
S中有多少个不重复的子序列。这里的子序列指,删掉
S
S
S中某些字符,剩下的字符按照原有的顺序拼成的字符串。
容易想到一个基本的DP解法:
设
d
p
i
dp_i
dpi?为以
S
i
S_i
Si?结尾(必选)的
S
[
1
,
i
]
S[1,i]
S[1,i]中的子序列的数量。特别的,设
d
p
0
=
0
dp_0=0
dp0?=0,对应一个空字符串。那么有如下转移方程:
d
p
i
=
∑
j
=
0
i
?
1
d
p
j
dp_i = \sum_{j = 0}^{i-1}dp_j
dpi?=j=0∑i?1?dpj?
但是我们会重复进行记录相同的子序列,因此我们改变一下DP方程:
d
p
i
=
∑
j
=
k
i
?
1
d
p
j
dp_i = \sum_{j = k}^{i-1}dp_j
dpi?=j=k∑i?1?dpj?
则此问题的答案为
∑
i
=
1
n
d
p
i
\sum_{i=1}^n dp_i
∑i=1n?dpi?。
其中
k
k
k是满足
S
k
=
S
i
S_k = S_i
Sk?=Si?中最大的
k
k
k,为什么这样可行呢?如果我们对小于
k
k
k的
d
p
j
dp_j
dpj?进行计数的话,则这个子序列已经被
d
p
k
dp_k
dpk?所计数过了,因此加到上述和中必然会重复计数,加到
S
k
S_k
Sk?后面是可行的,因为我们对原有的子序列的末尾长度增加了一。
例题
ABC 214F
|