一开始用一个f数组转移,发现不太对,状态有重叠部分
f[i][j][k]表示考虑了s的前i位,匹配到t的第j位,用了k个子串,且s的第i位必选
g[i][j][k]表示考虑了s的前i位,匹配到t的第j位,用了k个子串,且s的第i位必不选
考虑i的前一位:前一位选(作为结尾),前一位选(不作为结尾),前一位不选
f[i][j][k]=f[i-1][j-1][k]+f[i-1][j-1][k-1]+g[i-1][j-1][k-1]
第i位不选时继承状态
g[i][j][k]=g[i-1][j][k]+f[i-1][j][k]
滚动数组省一维
#include<iostream> #include<cstring> #include<cstdio> #define int long long using namespace std; inline int rd(){ int ret=0,f=1;char c; while(c=getchar(),!isdigit(c))f=c=='-'?-1:1; while(isdigit(c))ret=ret*10+c-'0',c=getchar(); return ret*f; } const int MAXN=1007; const int MOD=1000000007; int n,m,num; char s[MAXN],t[MAXN]; int f[2][MAXN][MAXN],g[2][MAXN][MAXN]; signed main(){ n=rd();m=rd();num=rd(); scanf("%s%s",s+1,t+1); s[0]='a';t[0]='b'; g[0][0][0]=1; for(int i=1;i<=n;i++){ g[i&1][0][0]=1; for(int j=1;j<=m&&j<=i;j++){ for(int k=1;k<=num;k++){ f[i&1][j][k]=g[i&1][j][k]=0; g[i&1][j][k]=(g[(i-1)&1][j][k]+f[(i-1)&1][j][k])%MOD; if(s[i]==t[j]){ f[i&1][j][k]=(f[(i-1)&1][j-1][k-1]+f[(i-1)&1][j-1][k]+g[(i-1)&1][j-1][k-1])%MOD; }else{ f[i&1][j][k]=0; } } } } cout<<(f[n&1][m][num]+g[n&1][m][num])%MOD; return 0; }