每日一道算法题之不同的子序列
- 一、题目
- 二、思路
- 三、C++代码
一、题目
题目来源:LeetCode【难度:困难】
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 109 + 7 取模。
示例如下:
输入:rabbbitrabbit
输出: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];}