问题一:统计字符串A中有多少个子序列 = 字符串 B
令dp(i , j) 为字符串A前i位,有多少个子序列 = B的前j位.
假设 B = XXLL
那么dp[i][1] 代表 子序列 "X"的个数
dp[i][2] 代表 子序列 "XX"的个数
dp[i][3] 代表 子序列 "XXL"的个数
dp[i][4] 代表 子序列 "XXLL"的个数
递推也很显然: XXLL 形成的条件是: 第i位为"L"且 1 ~ i - 1 中存在子序列 XXL
dp[i][j] = dp[i - 1][j] // 当 A[i] != B[j]
dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] // 当 A[i] = B[j]
问题二:你可以修改字符,使得字符串A中不存在子序列 = 字符串 B 的最小修改次数.
其实跟上面意思一样,这里就是求一个最优化。
利用自顶向下的方式,递归的去解决这个问题。
令dp[i][j]为A字符串前i个,使得不存在前j的B字符串的最少修改次数。
dp[i][j] = dp[i - 1][j] // 当 A[i] != B[j]
dp[i][j] = min(dp[i - 1][j - 1] + 1 , dp[i - 1][j - 1] ) // 当 A[i] = B[j] , 就是改或不改。
改的话,就往前。不改,那么就要求前i - 1 个数不存在 前j个B字符串。
还要注意到,给定的i, dp[i] 数组是非上升的。 因为限制条件越严格.
问题三:统计字符串中有多少个不同的字符串子序列
如果没有本质不同的限制 ,那么转移为 dp(i , j ) = dp(i - 1 , j) + dp(i - 1, j - 1).
有了本质不同。考虑当前一个以字母a结尾的长度为j的字符串集合.
....a
....a
.....a
那么当现在又遇到一个字母a,求它的长度为j的子序列的个数时,重复的部分就是之前以字母a结尾的长度为j的字符串个数 容斥掉这个部分即可。
答案就是 dp[n][1] + ... + dp[n][n]