一、题目
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 + 7 取模。
示例如下:
输入:rabbbit
rabbit
输出:3
二、思路
按照动态规划的解题步骤:
-
确定dp数组的含义
dp[i][j]:以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。 -
确定递推公式
分两种情况进行讨论,一种是s[i-1]与t[j-1]相等,一种是s[-1]与t[j-1]不相等的情况。
if(s[i-1]==t[j-1]){
dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
}else{
dp[i][j]=dp[i-1][j];
}
- dp数组初始化
for(int i=0;i<N;i++){
dp[i][0]=1;
}
for(int j=1;j<M;j++){
dp[0][j]=0;
}
- 确定遍历顺序
遍历的顺序一定是从上到下,从左到右。
三、C++代码
#include<bits/stdc++.h>
using namespace std;
//不同的子序列
#define maxn 10010
int dp[maxn][maxn]; //以i-1为结尾的s子序列中出现以j-1为结尾的t的个数为dp[i][j]。
int main(){
string s,t;
cin>>s>>t;
int N=s.size();
int M=t.size();
//dp数组初始化
for(int i=0;i<N;i++){
dp[i][0]=1;
}
for(int j=1;j<M;j++){
dp[0][j]=0;
}
//确定递推公式
for(int i=1;i<=N;i++){
for(int j=1;j<=M;j++){
if(s[i-1]==t[j-1]){
dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
}else{
dp[i][j]=dp[i-1][j];
}
}
}
cout<<dp[N][M];
}