P2679 子串
设$f[i][j][k][p]$表示匹配到A串第$i$个位置,B串第$j$个位置,已经匹配了$k$段,$p=0 or 1$表示A串的该位有没取
$p==1$时
$f[i][j][k][1]=f[i-1][j-1][k][1]+f[i-1][j-1][k-1][0]+f[i-1][j-1][k-1][1]$
$f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]$
$p==0$时
$f[i][j][k][1]=0$(不合法)
$f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]$
蓝后我们发现第一维可以滚动数组优化掉
那么时间$O(nmk)$空间$O(4m^{2})$就能过了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define re register 5 using namespace std; 6 const int p=1e9+7; 7 int n,m,kk,f[2][202][202][2]; 8 char a[1003],b[203]; 9 int main(){ 10 scanf("%d%d%d",&n,&m,&kk); 11 scanf("%s%s",a+1,b+1); 12 f[0][0][0][0]=f[1][0][0][0]=1; 13 for(re int i=1,t=1;i<=n;++i,t^=1) 14 for(re int j=1;j<=m;++j) 15 for(re int k=1;k<=kk;++k){ 16 if(a[i]==b[j])//字符相同可以取 17 f[t][j][k][1]=((f[t^1][j-1][k-1][0]+f[t^1][j-1][k-1][1])%p+f[t^1][j-1][k][1])%p; 18 else f[t][j][k][1]=0; 19 f[t][j][k][0]=(f[t^1][j][k][0]+f[t^1][j][k][1])%p; 20 } 21 printf("%d",(f[n&1][m][kk][0]+f[n&1][m][kk][1])%p); 22 return 0; 23 }