Substring Uva 11468_记忆化搜索 + AC自动机

 

Code:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=100;
const int maxd=400+3;
const int sigma=65;
double d[maxd][103],perc[sigma+3];
int ch[maxd][sigma+1],end1[maxd],f[maxd],last[maxd];
char A[30],mapp[sigma+3];
int cnt;
queue<int>Q;
int idx(char s){
	if(s>='a'&&s<='z')return s-'a';
	if(s>='A'&&s<='Z')return s-'A'+26;
	return s-'0'+52;
}
struct V
{
	void insert(char p[]){
		int n=strlen(p);
		int cur=0;
		for(int i=0;i<n;++i){
			int c=idx(p[i]);
			if(!ch[cur][c])ch[cur][c]=++cnt;
			cur=ch[cur][c];
		}
		end1[cur]=1,last[cur]=1;
	}
	void getfail(){
	   for(int i=0;i<sigma;++i)if(ch[0][i])Q.push(ch[0][i]);
		while(!Q.empty()){
			int r=Q.front();Q.pop();
			for(int i=0;i<sigma;++i){
				int u=ch[r][i];
				if(!u){ch[r][i]=ch[f[r]][i];continue;}
				Q.push(u);
				int v=f[r];
				while(v&&!ch[v][i])v=f[v];
				f[u]=ch[v][i];
				if(last[f[u]])last[u]=1;
			}
		}
	}                  
	double dp(int j,int L,int l,int n){
		if(end1[j]||last[j])return 0.0;
		if(L==l)return 1.0;
		if(d[j][L]>=0)return d[j][L];
		double ans=0.0;
		for(int i=1;i<=n;++i){
			int c=idx(mapp[i]);
			ans+=perc[i]*dp(ch[j][c],L+1,l,n);
		}
		d[j][L]=ans;
		return ans;
	}
}AC;
int main(){
	int T;scanf("%d",&T);
	for(int cas=1;cas<=T;++cas)
	{
	   memset(end1,0,sizeof(end1)); memset(d,-1,sizeof(d));
	   memset(f,0,sizeof(f)); memset(last,0,sizeof(last));
	   memset(ch,0,sizeof(ch));
	   cnt=0;
	   int k;scanf("%d",&k);
	   for(int i=1;i<=k;++i){scanf("%s",A);AC.insert(A);}
	   int n;scanf("%d",&n);char g=getchar();
	   for(int i=1;i<=n;++i)
	   	{scanf("%c",&mapp[i]); scanf("%lf",&perc[i]);g=getchar();}
	   int l;scanf("%d",&l);
	   AC.getfail();
	   double ans=AC.dp(0,0,l,n);
	   printf("Case #%d: ",cas);
	   printf("%.6f\n",ans);
	 }
	return 0;
}

  

posted @ 2018-09-19 20:58  EM-LGH  阅读(155)  评论(0编辑  收藏  举报