P2679 [NOIP2015 提高组] 子串

P2679 [NOIP2015 提高组] 子串

0x01 题意

给出字符串A和B,在A中取\(k\)个不重叠的子串,按原来的顺序排列后与B相同,求方案数

0x02 解

DP

\(f[i][j][p]\)为A字符串匹配到\(i\),B字符串匹配到\(j\)时,取\(p\)个子串且\(A_i\)为最后一位匹配成功的方案数,很好转移

为了求答案,我们需要\(f\)关于\(i\)的前缀和,定义为\(g\),有\(f[i][j][p]=\sum_Lg[i-L][j-L][p-1]\)

递推优化\(f[i][j][p]=f[i-1][j-1][p]+g[i-1][j-1][p-1]\)

因为只和上一项有关,所以可以优化成二维

0x03 码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1010,M=210,Mod=1000000007;

int f[N][M],n,m,k,g[N][N];
char a[N],b[M];

signed main(){
	
	cin>>n>>m>>k;
	scanf("%s%s",a+1,b+1);
	g[0][0]=1;
	for(int i=1;i<=n;i++)
		for(int j=min(m,i);j>=1;j--)
			for(int p=min(k,j);p>=1;p--){
				f[j][p]=a[i]==b[j]?(f[j-1][p]+g[j-1][p-1])%Mod:0;
				g[j][p]=(g[j][p]+f[j][p])%Mod;
			}
				
		
	cout<<g[m][k];
	
	return 0;
}
posted @ 2021-03-09 15:44  wsy_jim  阅读(196)  评论(0编辑  收藏  举报