题目链接:http://vjudge.net/contest/142513#problem/A

题意:给出一些字符和各自对应的选择概率,随机选择L次后将得到一个长度为L的随机字符串S.给出K个模版串,计算S不包含任何一个串的概率.

分析:

在构造好的AC自动机里面,每随机生成一个字母,相当于在AC自动机中随机走一步。所有单词结点标记为禁止,本题就是从结点 0 走 l 步,不进入任何禁止结点的概率。

#include <bits/stdc++.h>
using namespace std; const int SIGMA_SIZE = ;
const int MAXNODE = ; int idx[];
char s[][];
double prob[SIGMA_SIZE];
int n; struct AhoCorasickAutomata
{
int ch[MAXNODE][SIGMA_SIZE];
int f[MAXNODE];
int match[MAXNODE];
int sz; void init()
{
sz = ;
memset(ch[],,sizeof(ch[]));
} void insert(char *s)
{
int u = ,n = strlen(s);
for(int i=; i<n; i++)
{
int c = idx[s[i]];
if(!ch[u][c])
{
memset(ch[sz],,sizeof(ch[sz]));
match[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
match[u] = ;
} void getFail()
{
queue<int> q;
f[] = ;
for(int c=; c<SIGMA_SIZE; c++)
{
int u = ch[][c];
if(u)
{
f[u] = ;
q.push(u);
}
} while(!q.empty())
{
int r = q.front();
q.pop();
for(int c=; c<SIGMA_SIZE; c++)
{
int u = ch[r][c];
if(!u)
{
ch[r][c]=ch[f[r]][c];
continue;
}
q.push(u);
int v = f[r];
while(v&&!ch[v][c])
v = f[v];
f[u] = ch[v][c];
match[u] |=match[f[u]];
}
}
}
}; AhoCorasickAutomata ac; double d[MAXNODE][];
int vis[MAXNODE][]; double getProb(int u,int l)
{
if(!l) return 1.0;
if(vis[u][l]) return d[u][l];
vis[u][l] = ;
double& ans = d[u][l];
ans = 0.0;
for(int i=; i<n; i++)
{
if(!ac.match[ac.ch[u][i]])
ans += prob[i]*getProb(ac.ch[u][i],l-);
}
return ans;
} int main()
{
int T;
scanf("%d",&T);
for(int kase = ; kase<=T; kase ++)
{
int k,l;
scanf("%d",&k);
for(int i=; i<k; i++)
scanf("%s",s[i]); scanf("%d",&n);
for(int i=; i<n; i++)
{
char ch[];
scanf("%s%lf",ch,&prob[i]);
idx[ch[]] = i;
} ac.init();
for(int i=; i<k; i++)
ac.insert(s[i]);
ac.getFail();
scanf("%d",&l);
memset(vis,,sizeof(vis));
printf("Case #%d: %.6lf\n",kase,getProb(,l));
} return ;
}

AC自动机——Uva 11468 子串的更多相关文章

  1. 病毒侵袭持续中 - HDU 3065(AC自动机,判断子串个数)

    分析:依然是一个模板题,不过在写建立失败指针的地方竟然写错了三次....看来现在状态不太好.   代码如下: ============================================= ...

  2. Uva 11468 AC自动机或运算

    AC自动机 UVa 11468 题意:给一些字符和各自出现的概率,在其中随机选择L次,形成长度为L的字符串S,给定K个模板串,求S不包含任意一个串的概率. 首先介绍改良版的AC自动机: 传统的AC自动 ...

  3. UVa 11468 (AC自动机 概率DP) Substring

    将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. #include <cs ...

  4. UVA - 11468 (AC自动机+动态规划)

    建立AC自动机,把AC自动机当做一张图,在上面跑L个节点就行了. 参考了刘汝佳的代码,发现可能有一个潜在的Bug--如果模式串中出现了没有指定的字符,AC自动机可能会建立出错. 提供一组关于这个BUG ...

  5. 沉迷AC自动机无法自拔之:[UVA 11468] Substring

    图片加载可能有点慢,请跳过题面先看题解,谢谢 这个鬼题目,上一波套路好了 先用题目给的模板串建\(AC\)自动机,把单词结尾标记为 \(val=1\),然后在建好的\(AC\)自动机上跑 \(dp\) ...

  6. UVa 11468 Substring (AC自动机+概率DP)

    题意:给出一个字母表以及每个字母出现的概率.再给出一些模板串S.从字母表中每次随机拿出一个字母,一共拿L次组成一个产度为L的串, 问这个串不包含S中任何一个串的概率为多少? 析:先构造一个AC自动机, ...

  7. UVA 11468 Substring (AC自动机)

    用把失配边也加到正常边以后AC自动机,状态是长度递减的DAG,每次选一个不会匹配字符的转移. dp[u][L]表示当前在tire树上u结点长度还剩L时候不匹配的概率,根据全概率公式跑记忆化搜索. #i ...

  8. Substring UVA - 11468 AC自动机+概率DP

    题意: 给出一些字符和各自对应的选择概率,随机选择L次后得到一个长度为L的随机字符串S. 给出K个模板串,计算S不包含任何一个模板串的概率 dp[i][j]表示走到AC自动机 i 这个节点 还需要走 ...

  9. UVA 11468 AC 自动机

    首先我们应该是枚举 L个位置上的每个字符来得到最终概率 然后AC自动机的作用就是为了判断你枚举的地方是否对应了单词节点,如果对应了,就肯定要不得 #include <iostream> # ...

随机推荐

  1. strcat、strcpy、memcpy 的使用注意

    char *p = "hello";//5 个长度 ; //char *str = (char *)malloc(sizeof(char)*len); ] = "niha ...

  2. C++_static与非static成员(函数)

    static与非static成员(函数)  <C++ Primer>第4版399页: 对于特定类类型的全体对象而言,访问一个全局变量有时是必要的.然而,全局变量会破坏封装:对象需要支持特定 ...

  3. 火狐插件 Http请求利器 Httprequester

    搜索并且下载Httprequester

  4. BizTalk开发系列(三十三)BizTalk之Excel终极解决方案

    Excel作为优秀的客户端数据处理程序得到了广泛的应用. 由于其简单又强大的功能在很多公司或个人的数据处理中占用非常重要的位置. 而BizTalk作为微软的SOA主打产品虽然免费提供了很多Adapte ...

  5. Java之方法重载(笔记)

    Java是根据参数类型和个数的不同实现重载. 1.当参数类型是基本类型,但不完全匹配. void test(int i) { } void test(float f) { } public stati ...

  6. document获取节点byId&byName

    <script type="text/javascript"> /* *需要:获取页面中的DIV节点: *思路: *通过docment对象完成.因为div节点有ID属性 ...

  7. 精通JavaScript的this关键字

    小提示 阅读本文,您需要了解JS的基本常识.您将花费40分钟完成本文的阅读. JS中的this关键字让很多新老JS开发人员都感到困惑.这篇文章将对this关键字进行完整地阐述.读完本文以后,您的困惑将 ...

  8. XHTML表单

    1.HTML表单标记提供一套元素和属性,用来创建表单,收集网页参观者信息. 2.创建表单结构标记为<form>和</form>. 3.在<form>标记中,我们必须 ...

  9. 转: Linux磁盘扩容

    from:https://www.rootusers.com/how-to-increase-the-size-of-a-linux-lvm-by-expanding-the-virtual-mach ...

  10. 改变UIButton 图片和文字的位置

    //设置字体和图片之间的间距 _btnLeft.titleEdgeInsets = UIEdgeInsetsMake(0, -_btnLeft.imageView.frame.size.width, ...