f[i][j][k][0]表示a做到前i位,b做到前j位,有了k个子串且第i位不用的方案数
f[i][j][k][1]表示a做到前i位,b做到前j位,有了k个子串且第i位用的方案数
a[i]==b[j]:
f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
f[i][j][k][1]=f[i-1][j-1][k][1]+f[i-1][j-1][k-1][1]+f[i-1][j-1][k-1][0]
a[i]!=a[j]
f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
f[i][j][k][1]=0
滚动数组优化即可通过本题
#include<cstdio> using namespace std; const long long mod=1000000007; long long f[2][205][205][2]; int n,m,k; char a[1005],b[1005]; int main(){ f[0][0][0][0]=f[1][0][0][0]=1ll; scanf ("%d%d%d",&n,&m,&k); scanf ("%s",a+1);scanf ("%s",b+1); for (register int i=1;i<=n;++i){ for (register int j=1;j<=m;++j){ for (register int w=1;w<=k;++w){ if (a[i]==b[j]){ f[i%2][j][w][0]=f[(i-1)%2][j][w][0]+f[(i-1)%2][j][w][1]; f[i%2][j][w][1]=f[(i-1)%2][j-1][w][1]+f[(i-1)%2][j-1][w-1][1]+f[(i-1)%2][j-1][w-1][0]; } else{ f[i%2][j][w][0]=f[(i-1)%2][j][w][0]+f[(i-1)%2][j][w][1]; f[i%2][j][w][1]=0; } f[i%2][j][w][0]%=mod; f[i%2][j][w][1]%=mod; } } } printf ("%lld\n",(f[n%2][m][k][0]+f[n%2][m][k][1])%mod); return 0; }