codeforces163A

给你两个串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 } 
View Code

猜你喜欢

转载自www.cnblogs.com/pandaking/p/9985065.html