P2679 子串

链接:Miku


\(dp_{i,j,k,0/1}\)表示A串

应该

取i,j个的时候的方案数

然后要考虑的就是

如果\(a_{i-1}\)==\(b_{j-1}\)

那么\(dp_{i,j,k,1}\)=\(dp_{i-1,j-1,k,1}\)+\(dp_{i-1,j-1,k-1,1}\)+\(dp_{i-1,j-1,k-1,0}\)
//其实也就是拼到原来的上,在原来的后面强拆一个,正常的新建一个
反之 \(dp_{i,j,k,1}\)=0;

然后对于所有的\(dp_{i,j,k,0}\)=\(dp_{i-1,j,k,1}\)+\(dp_{i-1,j,k,0}\)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int n,m,k,z;
string a,b;
//用char会有奇怪的格式问题
int f[2][1001][300][2];
int mod=1000000007;
int main(){
	scanf("%d%d%d",&n,&m,&z);
	cin>>a>>b;
//	cout<<a[0];
	f[1][0][0][0]=f[0][0][0][0]=1;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=m;++j){
			for(int k=1;k<=z;++k){
				if(a[i-1]==b[j-1]){
					f[i%2][j][k][1]=((f[(i+1)%2][(j-1)][k][1]+f[(i+1)%2][(j-1)][k-1][1])%mod+f[(i+1)%2][(j-1)][k-1][0])%mod;
					f[i%2][j][k][0]=(f[(i+1)%2][j][k][1]+f[(i+1)%2][j][k][0])%mod;
				}else{
					f[i%2][j][k][1]=0;
					f[i%2][j][k][0]=(f[(i+1)%2][j][k][1]+f[(i+1)%2][j][k][0])%mod;
				} 
			}
		}
	}
	cout<<(f[(n)%2][m][z][0]+f[(n)%2][m][z][1])%mod;
	return 0;
} 
posted @ 2020-09-19 21:40  Simex  阅读(100)  评论(0编辑  收藏  举报