• UVA11468 Substring


    好久不做 (AC) 自动机题了,今天水一道

    Description

    link

    给定一些字符串,然后给出每个字符的概率 (p_i),和一个长度 (L)

    我们现在要构造一个长度为 (L) 的字符串,对于这个字符串的每个位置,每个字符有 (p_i) 的概率出现在这个位置

    求有多大的概率在这个长度为 (L) 的字符串中不出现任何一个给定的字符串

    数据范围? (O() 能过 ())

    Solution

    先把所有的字符建个自动机,末尾节点打上标记,要与上 (fail) 节点的标记(原因显然)

    然后就是个无脑 (dp)

    (f_{i,j}) 为当前长度为 (i) 的,匹配到节点 (j) 的概率

    暴力转移一下即可

    最后(ans=sumlimits_{i=1}^{tot} f_{l,i})

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=1010;
    	map<char,int> id;
    	inline void prework()
    	{
    		int cnt=0;
    		for(int i=0;i<26;++i) id['a'+i]=++cnt;
    		for(int i=0;i<26;++i) id['A'+i]=++cnt;
    		for(int i=0;i<10;++i) id['0'+i]=++cnt;
    		return ; 
    	}
    	int n,m,ch[N][70],fail[N],tot,cnt,fl[N],l;	
    	double p[N],f[110][N];
    	char s[N];
    	inline void insert()
    	{
    		int len=strlen(s+1),now=0;
    		for(int i=1;i<=len;++i) 
    		{
    			if(!ch[now][id[s[i]]]) ch[now][id[s[i]]]=++tot;
    			now=ch[now][id[s[i]]]; 
    		}fl[now]=1;
    		return ;
    	}
    	inline void bfs()
    	{
    		queue<int> q;
    		for(int i=1;i<=62;++i) 
    		{
    			if(ch[0][i]) q.push(ch[0][i]),fail[ch[0][i]]=0;
    		}
    		while(!q.empty())
    		{
    			int fr=q.front(); q.pop();
    			for(int i=1;i<=62;++i)
    			{
    				if(ch[fr][i]) fail[ch[fr][i]]=ch[fail[fr]][i],q.push(ch[fr][i]);
    				else ch[fr][i]=ch[fail[fr]][i];
    			}fl[fr]|=fl[fail[fr]];
    		} 
    		return ;
    	}
    	inline void work()
    	{	
    		n=read(); 
    		memset(ch,0,sizeof(ch)); 
    		memset(fail,0,sizeof(fail));
    		memset(fl,0,sizeof(fl));
    		memset(f,0,sizeof(f)); tot=0;
    		memset(p,0,sizeof(p));
    		for(int i=1;i<=n;++i) scanf("%s",s+1),insert();
    		bfs(); m=read(); f[0][0]=1;
    		for(int i=1;i<=m;++i) 
    		{
    			char s; cin>>s; 
    			double tmp; scanf("%lf",&tmp); 
    			p[id[s]]+=tmp;
    		} l=read(); 
    		for(int i=1;i<=l;++i)
    		{
    			for(int j=0;j<=tot;++j) 
    			{
    				for(int k=1;k<=62;++k)
    				{
    					if(!fl[ch[j][k]]) f[i][ch[j][k]]+=f[i-1][j]*p[k];
    				}
    			}
    		}
    		double ans=0;
    		for(int i=0;i<=tot;++i) ans+=f[l][i];
    		printf("Case #%lld: %.6lf
    ",++cnt,ans);
    		return ;
    	}
    	signed main()
    	{
    		prework();
    		int T=read(); while(T--) work();
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
    
  • 相关阅读:
    数据科学工作中存在的7大问题与解决方案
    搞定SEO,看这一篇就够了
    李宏毅老师机器学习课程笔记_ML Lecture 3-1: Gradient Descent
    李宏毅老师机器学习课程笔记_ML Lecture 2: Where does the error come from?
    李宏毅老师机器学习课程笔记_ML Lecture 1: ML Lecture 1: Regression
    李宏毅老师机器学习课程笔记_ML Lecture 1: 回归案例研究
    python爬取中国大学排名
    爬虫实战_爬取静态单张图片
    李宏毅老师机器学习课程笔记_ML Lecture 0-2: Why we need to learn machine learning?
    多线程基础(一)
  • 原文地址:https://www.cnblogs.com/yspm/p/13287665.html
Copyright © 2020-2023  润新知