给你两个串a和b,让你求a中的子串是b中的子序列的个数!
不妨假设状态如下:DP[I][J],表示该子串以a[i]结尾,然后求b序列列前j个字符中有多少种方式,那么最后的答案就是sum(dp[1][strlen(b)]+......dp[strlen(a)][strlen(b)]),状态不难想,怎么想转移方程呢。
首先如果a[i]不等于b[j],由于是以a[i]字符结尾,那么b[j]就无法做出贡献,那么dp[i][j]=dp[i][j-1];
如果a[i]等于b[j],我们先考虑不把b[j]看进来,就有dp[i][j]=dp[i][j-1],又由于a[i]和b[j]相等,那么dp[i][j]++。由于a[i]和b[j]相等,那么已经保证了以a[i]结尾,那么便可以加上一个dp[i-1][j-1];
接下来是代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 char s1[5100]; 4 char s2[5100]; 5 int dp[5100][5100]; 6 const int mod=1000000007; 7 int main(){ 8 scanf("%s",s1+1); 9 scanf("%s",s2+1); 10 int len1=strlen(s1+1); 11 int len2=strlen(s2+1); 12 int ans=0; 13 for(int i=1;i<=len1;i++){ 14 for(int j=1;j<=len2;j++){ 15 if(s1[i]==s2[j]) dp[i][j]=(dp[i-1][j-1]+1)%mod; 16 dp[i][j]=(dp[i][j]+dp[i][j-1])%mod; 17 } 18 ans=(ans%mod+dp[i][len2]%mod)%mod; 19 } 20 cout<<ans<<endl; 21 return 0; 22 }