P2679 子串

(f_{i,j,l,0/1}) 表示 (A) 中前 (i) 个字符,取出 (l) 个子串,拼成了 (B) 中前 (j) 个字符,第 (i) 个字符取/不取的方案数。

不取直接累加 (A) 中上一个字符的状态。

[f_{i,j,l,0}=f_{i-1,j,l,0}+f_{i-1,j,l,1} ]

取就分接在上一个子串和新开一个子串讨论。

[f_{i,j,1}=f_{i-1,j-1,l,1}+f_{i-1,j-1,l-1,0}+f_{i-1,j-1,l-1,1} ]

然后这题就做完了,记得滚动数组,取模和初始化。

时间复杂度 (O(nmk))

code:

#include<bits/stdc++.h>
using namespace std;
#define N 2
#define NN 205
#define Mod 1000000007
#define For(i,x,y)for(i=x;i<=(y);i++)
#define Mems(i,j)memset(i,j,sizeof i)
#define Memc(i,j)memcpy(i,j,sizeof i)
string a,b;
int f[NN][NN][N],g[NN][NN][N];
int main()
{
	int n,m,i,j,k,l;
	cin>>n>>m>>k>>a>>b;
	g[0][0][0]=1;
	For(i,1,n)
	{
		f[0][0][0]=1;
		For(j,1,m)
		For(l,1,k)
		{
			if(a[i-1]==b[j-1])f[j][l][1]=((g[j-1][l][1]+g[j-1][l-1][0])%Mod+g[j-1][l-1][1])%Mod;
			f[j][l][0]=(g[j][l][1]+g[j][l][0])%Mod;
		}
		Memc(g,f);
		Mems(f,0);
	}
	cout<<(g[m][k][0]+g[m][k][1])%Mod;
	return 0;
}
原文地址:https://www.cnblogs.com/May-2nd/p/13802973.html