2 a b aa ab
1 2
注:DP d(i, j)表示最长公共子串长度 f(i, j)表示长度为d(i,j)的子串存在于Y中的数目
递推公式:很简单,选择一个条件,然后分析情况
这里选择取不取X(i)
I. if d(i, j) == d(i-1, j) then f(i, j) += f(i-1, j);
II.if d(i, j) == d(i-1, p-1) + 1 | X(i)==Y(p) && p<=j then f(i, j) += f(i-1, p-1).
Node: Initial Conditions--d(0,i) = d(i, 0) = 0, f(0, i) = f(0, i) = 1, f(i, j) = 0;
<pre name="code" class="cpp">#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 1005
#define MOD 1000000007
char s1[maxn], s2[maxn];
int d[maxn][maxn];
int f[maxn][maxn];
int pos[maxn][27];
void solve()
{
int len1 = strlen(s1+1);
int len2 = strlen(s2+1);
memset(f, 0, sizeof(f));
for(int i=0; i<=len2; i++)
{
d[0][i] = d[i][0] = 0;
f[0][i] = f[i][0] = 1;
}
for(int i=1; i<=len1; i++)
for(int j=1; j<=len2; j++)
if(s1[i] == s2[j])
d[i][j] = d[i-1][j-1] + 1;
else
d[i][j] = max(d[i-1][j], d[i][j-1]);
memset(pos, 0, sizeof(pos));
for(int i=1; i<=len2; i++)
{
for(int j=0; j<26; j++)
pos[i][j] = pos[i-1][j];
pos[i][s2[i]-'a'] = i;
}
f[0][0] = 1;
for(int i=1; i<=len1; i++)
for(int j=1; j<=len2; j++)
{
if(d[i][j] == 0)
{
f[i][j] = 1;
continue;
}
if(d[i][j] == d[i-1][j])
f[i][j] = (f[i][j] + f[i-1][j]) % MOD;
int p = pos[j][s1[i]-'a'];
if(p && d[i][j] == d[i-1][p-1] + 1)
f[i][j] = (f[i][j] + f[i-1][p-1]) % MOD;
}
printf("%d\n", f[len1][len2]);
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int T;
cin>>T;
while(T--)
{
scanf("%s", s1+1);
scanf("%s", s2+1);
solve();
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/dojintian/article/details/46928605