给定两个字符串A,B(都是由a,b组成)(长度分别为n,m);你可以在A中任按顺序截取k个字串组成B,问能截取的个数
动态规划;
s[i][j][k]:数组A到第i项了,数组B到第j项了,总方案数;
f[i][j][k]:数组A到第i项了,数组B到第j项了,必须有A的第[i]项的总方案数;
当a[i]=b[j]时;
f[i][j][k]=f[i-1][j-1][k]+s[i-1][j-1][k-1];
s[i][j][k]=s[i-1][j-1][k]+f[i][j][k];
当a[i]!=b[j]时;
f[i][j][k]=0;
s[i][j][k]=s[i-1][j][k];
//注意-1超边界
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
#define fo(a,b,c) for(int a=(b);a<=(c);a++)
const int mod=1000000007;
char a[1005],b[205];
int s[2][205][205],f[2][205][205],n,m,h;
void solve()
{
int pre=1;
int now=0;
s[pre][0][0]=1;
fo(i,0,n-1)
{
s[now][0][0]=1;
fo(j,0,m-1)
{
fo(k,1,min(h,j))
if(a[i]==b[j])
{
f[now][j][k]=(f[pre][j-1][k]+s[pre][j-1][k-1])%mod;
s[now][j][k]=(f[now][j][k]+s[pre][j][k])%mod;
}
else
{s[now][j][k]=s[pre][j][k];
f[now][j][k]=0;
}
}
pre^=1;
now^=1;
}
cout<<s[pre][m-1][h]%mod;
}
int main()
{
scanf("%d%d%d%s%s",&n,&m,&h,a,b);
solve();
return 0;
}