HDU-5763 Another Meaning

题意:t组询问,每次给出串(a,b),串(a)中与(b)相等的字串可以替换为(*),问a可以变为多少种字符串。

KMP+DP,从前往后(dp)(a)的每一个位置,设枚举到(i),如果(a[i-len(b) ... i]==b),那么我们就可以选择是否将这个字串替换,答案就等于不替换的方案数((f[i-1]))加替换的方案数((f[i-len(b)]))。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+100,P=1e9+7;
int n,m,t,nex[maxn],ok[maxn],k,f[maxn];
char a[maxn],b[maxn];
void getnex(){
	nex[1]=0,k=0;
	for(int i=2;i<=n;i++){
		while(k>0&&b[k+1]!=b[i])
			k=nex[k];
		if(b[k+1]==b[i])
			k++;
		nex[i]=k;
	}
}
int main(){
	scanf("%d",&t);
	for(int o=1;o<=t;o++){
		scanf("%s%s",a+1,b+1);
		n=strlen(a+1),m=strlen(b+1);
		memset(ok,0,sizeof(ok));
		getnex();
		for(int i=0,j=0;i<=n;i++){
			if(j>0&&a[i+1]!=b[j+1])
				j=nex[j];
			if(a[i+1]==b[j+1])
				j++;
			if(j==m){
				ok[i+1]=1;
				j=nex[j];
			}
		}
		f[0]=1;
		for(int i=1;i<=n;i++){
			f[i]=f[i-1];
			if(ok[i])
				f[i]+=f[i-m],f[i]%=P;
                //这里可以让f[i]+=1,前面f[0]=0,
                //后面输出f[n]+1,不知道为什么能对?
		}
		printf("Case #%d: %d
",o,f[n]);
	}
}
原文地址:https://www.cnblogs.com/nianheng/p/9905633.html