您的位置:首页 > 其它

UVa11468 - Substring(AC+dp+概率)

2017-10-30 07:06 483 查看
题目链接

简介:

给出一些字符和各自出现的概率,随机选择L次后将得到一个长度为L的随机字符串S,

再给出K个模式串,计算S中不含任何一个模式串的概率

分析:

这道题就是文本生成器的变式

我们先把所有串扔到一个AC自动机上所有单词结尾都设成false(不能到达)

在建立fail指针的时候,用失配的可到达性维护结点的可到达性

ed[ch[now][i]]|=ed[fail[ch[now][i]]];    //儿子的ed  儿子fail的ed


之后就是记忆化搜索版本的dp

每随机生成一个字母,相当于在AC自动机上走了一步

设f(i,j)表示当前结点为i,还需要走j步

转移方程:f(i,j)=sum{P[i]*f(k,j-1)|k是i的后继且可到达结点}

tip

本题的字典是给出的

所以我们需要一个map映射一下,构建AC自动机上以及dp都是在新的字典的基础上

数组要开够

//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<map>

using namespace std;

int ch[405][70];
int K,tot,fail[405],n,m;
char s[21][21];
bool ed[405],vis[405][105];
double P[70],f[405][105];
map<char,int> mp;

void insert(char *s)
{
int now=0;
int len=strlen(s);
for (int i=0;i<len;i++)
{
int x=mp[s[i]];
if (!ch[now][x]) ch[now][x]=++tot;
now=ch[now][x];
}
ed[now]=1;
}

void make()
{
queue<int> Q;
for (int i=0;i<m;i++)
if (ch[0][i]) Q.push(ch[0][i]);

while (!Q.empty())
{
int now=Q.front(); Q.pop();
for (int i=0;i<m;i++)
{
if (!ch[now][i])
{
ch[now][i]=ch[fail[now]][i];
continue;
}
fail[ch[now][i]]=ch[fail[now]][i];
ed[ch[now][i]]|=ed[fail[ch[now][i]]];    //儿子的ed  儿子fail的ed
Q.push(ch[now][i]);                      //容易漏写
}
}
}

double doit(int u,int L)
{
if (!L) return 1.0;
if (vis[u][L]) return f[u][L];

vis[u][L]=1;
double &ans=f[u][L];
ans=0.0;
for (int i=0;i<m;i++)              //m
if (!ed[ch[u][i]])
ans+=P[i]*doit(ch[u][i],L-1);
return ans;
}

int main()
{
int T;
scanf("%d",&T);
for (int cas=1;cas<=T;cas++)
{
tot=0;
memset(ed,0,sizeof(ed));
memset(vis,0,sizeof(vis));
memset(ch,0,sizeof(ch));
memset(fail,0,sizeof(fail));
memset(f,0,sizeof(f));
mp.clear();

scanf("%d",&K);
for (int i=1;i<=K;i++)
scanf("%s",&s[i]);

scanf("%d",&m);
for (int i=0;i<m;i++)            //m个字符,重新编号
{
char opt[2];
scanf("%s",&opt);
scanf("%lf",&P[i]);
mp[opt[0]]=i;
}

for (int i=1;i<=K;i++)
insert(s[i]);
make();

scanf("%d",&n);
printf("Case #%d: %0.6lf\n",cas,doit(0,n));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: