一道不是很远古的联赛题。
由于联赛快到了,这里就写一写有理有据的思考过程:
显然应该往
DP
方向思考。先想到的应该是
fi,j,k
表示a串前
i
个,已经把b串前
这样状态数已经比较大了,而且感觉不太能再少记一点东西。只能考虑优化转移的复杂度了。我们需要做到
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn=1005,maxm=205,MOD=1e9+7;
typedef long long LL;
using namespace std;
int n,m,K,f[2][maxm][maxm][2];
char a[maxn],b[maxn];
int main(){
freopen("hh.in","r",stdin);
freopen("hh.out","w",stdout);
scanf("%d%d%d%s%s",&n,&m,&K,a+1,b+1);
f[0][0][0][0]=1;
for(int i=1;i<=n;i++){
memset(f[i&1],0,sizeof(f[i&1]));
f[i&1][0][0][0]=1;
for(int j=1;j<=m;j++)
for(int k=1;k<=K;k++){
f[i&1][j][k][0]=(f[(i&1)^1][j][k][0]+f[(i&1)^1][j][k][1])%MOD;
if(a[i]==b[j]) f[i&1][j][k][1]=((LL)f[(i&1)^1][j-1][k-1][0]+f[(i&1)^1][j-1][k-1][1]+f[(i&1)^1][j-1][k][1])%MOD;
}
}
printf("%d\n",(f[n&1][m][K][0]+f[n&1][m][K][1])%MOD);
return 0;
}