题目大意:给定两个字符串A,B(都是由a,b组成)(长度分别为n,m);你可以在字符串A中任截取k个字符串按截取顺序组成字符串B,问能截取的方案数
动态规划;
s[i][j][k]:字符串A正要处理第i项了,数组B匹配正要第j项,已经截取了k个字符串,总方案数;
f[i][j][k]:字符串A正要处理第i项了,数组B匹配正要第j项了,已经截取了k个字符串,且第k个字符串必须包含A的第i项的总方案数;
考虑怎么转移
当a[i]=b[j]时;
f[i][j][k]=f[i-1][j-1][k]+s[i-1][j-1][k-1];//把a[i]放进以前截好的的第k段的末尾 和 a[i]单独成第k段。
s[i][j][k]=s[i-1][j-1][k]+f[i][j][k];
当a[i]!=b[j]时;
f[i][j][k]=0;//第k段,不可能有a[i].
s[i][j][k]=s[i-1][j][k];(s[i][j][k]=s[i-1][j][k] + 0);
//注意-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;
long long ans = 0;
void solve()
{
int pre=1;
int now=0;
s[pre][0][0]=1;
fo(i,1,n)
{
s[now][0][0]=1;
fo(j,1,m)
{
fo(k,1,min(h,j))
if(a[i-1]==b[j-1])
{
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][h]%mod;
}
int main()
{
//freopen("ha.in","r",stdin);
scanf("%d%d%d%s%s",&n,&m,&h,a,b);
solve();
return 0;
}