UVA11468 Substring
Posted yspm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA11468 Substring相关的知识,希望对你有一定的参考价值。
好久不做 (AC) 自动机题了,今天水一道
Description
给定一些字符串,然后给出每个字符的概率 (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();}
以上是关于UVA11468 Substring的主要内容,如果未能解决你的问题,请参考以下文章
UVA_11468_Substring_(AC自动机+概率动态规划)