传送门
洛谷:https://daniu.luogu.org/problem/show?pid=2679
UOJ:http://uoj.ac/problem/149
解题分析
一开始感觉像01背包,不过推了好久模型都建不起来,然后看了题解,三维的
f[i][j][k][0/1] 表示A串匹配到第i位,B串匹配到第j位,用了k个子串的方案数,其中第i位不要/要加入
那么如果不要i,就直接前一状态
如果要i,那就分是否跟前面一个子串连起来,如果连,说明i-1位也要选,推
注意到都是i-1,可以滚动数组优化空间。
复杂度:
时间:
空间:
#include<cstdio>
#include<cstring>
using namespace std;
const int tt=1e9+7;
int n,m,p,f[2][205][205][2];
char a[1005],b[205];
int main()
{
freopen("substring.in","r",stdin);
freopen("substring.out","w",stdout);
scanf("%d%d%d",&n,&m,&p); scanf("%s%s",a+1,b+1);
memset(f,0,sizeof(f)); f[0][0][0][0]=1;
for (int i=1,c=1;i<=n;i++,c^=1){
memset(f[c],0,sizeof(f[c]));
f[c][0][0][0]=1;
for (int j=1;j<=m;j++)
for (int k=1;k<=p;k++){
f[c][j][k][0]=(f[c^1][j][k][0]+f[c^1][j][k][1])%tt;
if (a[i]==b[j]) f[c][j][k][1]=((long long)f[c^1][j-1][k-1][1]+f[c^1][j-1][k][1]+f[c^1][j-1][k-1][0])%tt;
}
}
printf("%d\n",(f[n&1][m][p][0]+f[n&1][m][p][1])%tt);
return 0;
}