小伙伴们好,卷卷毛又来了,今天来分享一个非常具有技巧性的题目。
这是一道状态统计题目,同时兼具了若干技巧,有优化空间复杂度的数组减维,还有处理超大数据运算的高精度以及压位处理…也许这些技巧中有小伙伴们不熟悉的词汇,不过不要紧张,在下面对题目的分析中,我们会一一讨论到。
题面
那我们话不多说,先看题目:
时空限制:
输入样例:
1414
BE
输出样例:
3
分析与实现
题目大意是,给定两个字符串作为原文和密文。译码后,密文为原文的一个子序列(注意不是子串,不必在原文中连续出现)。问将密文还原为原文有多少种还原方式。
分析
简单分析题目,在将源码转成译码之后就是一道方案统计的问题。一般来说,方案统计的问题也需要借助状态之间的转移,所以我们也总是将这种方案统计的问题与动态规划问题统称为DP,尽管这类问题不涉及最优解。
所以,这个问题我们依旧可以使用之前用来解决动态规划问题的思想,在状态转移的过程中完成对结果方案的统计,即:定状态,找转移,初始化。
(顺便打个广告,之前动态规划相关的文章在这里:区间动态规划 例题与解析, 最短路径的方案数统计问题(基于floyd算法), 背包dp问题:背包九讲)
好了,我们言归正传~
定状态
对于这个问题,我们可以定义状态:
d p [ i ] [ j ] ( j ≤ i , 0 ≤ i ≤ n , 0 ≤ j ≤ m ) n = l e n ( A ) m = l e n ( B ) dp[i][j](j \le i,0 \le i \le n,0 \le j \le m) \\ n = len(A) \\ m = len(B) dp[i][j](j≤i,0≤i≤n,0≤j≤m)n=len(A)m=len(B)
表示 a 1 a 2 . . a i a_1a_2..a_i a1a2..ai与 b 1 b 2 . . b j b_1b_2..b_j b1b2..bj补全匹配的方案数
找转移
定义好了状态,来处理状态间的转移。
可以分成两种情况:
- 当 a i a_i ai与 b j b_j bj不相同时, d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i - 1][j] dp[i][j]=dp[i−1][j],即最后一位不匹配,方案数同上一位 a i − 1 a_{i-1} ai−1匹配到 b j b_j bj相同。
- 当 a i a_i ai与 b j b_j bj相同时, d p [ i ] [ j ] = d p [ i − 1 ] [ j − 1 ] + d p [ i − 1 ] [ j ] dp[i][j]=dp[i - 1][j - 1] + dp[i - 1][j] dp[i][j]=dp[i−1][j−1]+dp[i−1][j],即可以取最后一位不匹配,方案数同上;加上可以取最后一位匹配,方案数取上一位 a i − 1 a_{i-1}