题目描述:
示例1:
示例2:
分析:子序列问题一般都可以用动态规划解决,先规定dp[i][j]表示再s串的前i个字符中,出现子序列为t串前j个字符的次数。状态转移,一共有两种状态,一种s串的第i个字符等于t串的第j个字符,另一种是s串中第i个字符不等于t串中的第j个字符,因此可以写出状态转移方程:
(1)相等的情况:dp[i][j]=dp[i-1][j-1]+dp[i-1][j];//若用将s[i]与t[j]匹配,则问题转化为s串前i-1个字符中,出现子序列为t串中前j-1个字符的次数,若没有将s[i]与t[i]匹配,则问题转化为s串前j-1个字符中,出现子序列为t串前j个字符的次数。
(2)不相等的情况:dp[i][j]=dp[i-1][j];//不能匹配,则出现的次数即为s串中前i-1个字符中出现的次数。
class Solution {
public:
int numDistinct(string s, string t)
{
int n=s.size(),m=t.size();
if(n<m)
return 0;
vector<vector<unsigned long long>> dp(n + 1, vector<unsigned long long>(m + 1));
for(int i=0;i<n;i++)
dp[i][0]=1;
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];
}
}
return dp[n][m];
}
};