[NOIP 2015] 子串
[题目链接]
[算法]
动态规划
f[i][j][k][0 / 1]表示在A的前i位中选j个互不重叠的子串,与B的前k位相同,第i位选 / 不选的方案数
可以用滚动数组优化空间复杂度
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 1010 #define MAXM 210 const int P = 1000000007; int i,j,k,x,n,m,t; long long f[2][MAXM][MAXM][2]; char a[MAXN],b[MAXM]; int main() { scanf("%d%d%d",&n,&m,&t); scanf("%s%s",a + 1,b + 1); f[0][0][0][0] = 1; for (i = 1; i <= n; i++) { for (j = 0; j <= min(i,t); j++) { for (k = 0; k <= m; k++) { f[i & 1][j][k][0] = f[i & 1][j][k][1] = 0; f[i & 1][j][k][0] = (1ll * f[(i - 1) & 1][j][k][0] + 1ll * f[(i - 1) & 1][j][k][1]) % P; if (j == 0 || k == 0) continue; if (a[i] == b[k]) f[i & 1][j][k][1] = (1ll * f[(i - 1) & 1][j - 1][k - 1][0] + 1ll * f[(i - 1) & 1][j - 1][k - 1][1] + 1ll * f[(i - 1) & 1][j][k - 1][1]) % P; } } } printf("%lld\n",(f[n & 1][t][m][0] + f[n & 1][t][m][1]) % P); return 0; }