题意:给你 k 个模板串,然后给你一些字符的出现概率,然后给你一个长度 l ,问你这些字符组成的长度为 l 的字符串不包含任何一个模板串的概率。

思路:AC自动机+概论DP

首先用K个模板构造好AC自动机。题目上说长L的新串的子串不包含任何一个K串,其实就是说在构造好的树中,从根往下走L步都不包含K个模板。此题用match标记是否为K模板串。

状态转移方程代码中注释了。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<cstdio>
  5. #include<map>
  6. #include<string>
  7. using namespace std;
  8.  
  9. const int SIGMA_SIZE = ;
  10. const int MAXNODE = ; // 结点总数
  11. const int MAXS = + ; // 模板个数
  12.  
  13. int idx[], n;
  14. double prob[SIGMA_SIZE];
  15.  
  16. struct AhoCorasickAutomata
  17. {
  18. int ch[MAXNODE][SIGMA_SIZE];
  19. int f[MAXNODE]; // fail函数
  20. int match[MAXNODE]; // 是否包含某一个字符串
  21. int sz; // 结点总数
  22.  
  23. void init()
  24. {
  25. sz = ;
  26. memset(ch[], , sizeof(ch[]));
  27. }
  28.  
  29. // 插入字符串
  30. void insert(char *s)
  31. {
  32. int u = , n = strlen(s);
  33. for(int i = ; i < n; i++)
  34. {
  35. int c = idx[s[i]];
  36. if(!ch[u][c])
  37. {
  38. memset(ch[sz], , sizeof(ch[sz]));
  39. match[sz] = ;
  40. ch[u][c] = sz++;
  41. }
  42. u = ch[u][c];
  43. }
  44. match[u] = ;
  45. }
  46.  
  47. // 计算fail函数
  48. void getFail()
  49. {
  50. queue<int> q;
  51. f[] = ;
  52. // 初始化队列
  53. for(int c = ; c < SIGMA_SIZE; c++)
  54. {
  55. int u = ch[][c];
  56. if(u)
  57. {
  58. f[u] = ;
  59. q.push(u);
  60. }
  61. }
  62. // 按BFS顺序计算fail
  63. while(!q.empty())
  64. {
  65. int r = q.front();
  66. q.pop();
  67. for(int c = ; c < SIGMA_SIZE; c++)
  68. {
  69. int u = ch[r][c];
  70. if(!u)
  71. {
  72. ch[r][c] = ch[f[r]][c];
  73. continue;
  74. }
  75. q.push(u);
  76. int v = f[r];
  77. while(v && !ch[v][c]) v = f[v];
  78. f[u] = ch[v][c];
  79. match[u] |= match[f[u]];
  80. }
  81. }
  82. }
  83. };
  84.  
  85. AhoCorasickAutomata ac;
  86.  
  87. double d[MAXNODE][];
  88. int vis[MAXNODE][];
  89.  
  90. double getProb(int u, int L)//d[u][L]=prob[u]*d[v][L-1]状态转方程 v为u的儿子可以走节点
  91. {
  92. if(!L) return 1.0;
  93. if(vis[u][L])
  94. return d[u][L];
  95. vis[u][L] = ;
  96. d[u][L]=0.0;
  97. for(int i = ; i < n; i++)
  98. if(!ac.match[ac.ch[u][i]])
  99. d[u][L] += prob[i] * getProb(ac.ch[u][i], L-);
  100. return d[u][L];
  101. }
  102.  
  103. char s[][];
  104.  
  105. int main()
  106. {
  107. int T;
  108. scanf("%d", &T);
  109. for(int kase = ; kase <= T; kase++)
  110. {
  111. int k, L;
  112. scanf("%d", &k);
  113. for(int i = ; i < k; i++) scanf("%s", s[i]);
  114. scanf("%d", &n);
  115. for(int i = ; i < n; i++)
  116. {
  117. char ch[];
  118. scanf("%s%lf", ch, &prob[i]);
  119. idx[ch[]] = i;
  120. }
  121. ac.init();
  122. for(int i = ; i < k; i++) ac.insert(s[i]);
  123. ac.getFail();
  124. scanf("%d", &L);
  125. memset(vis, , sizeof(vis));
  126. memset(d,,sizeof(d));
  127. printf("Case #%d: %.6lf\n", kase, getProb(, L));
  128. }
  129. return ;
  130. }

uva 11468 Substring的更多相关文章

  1. uva 11468 - Substring(AC自己主动机+概率)

    题目链接:uva 11468 - Substring 题目大意:给出一些字符和各自字符相应的选择概率.随机选择L次后得到一个长度为L的字符串,要求该字符串不包括随意一个子串的概率. 解题思路:构造AC ...

  2. AC自动机+全概率+记忆化DP UVA 11468 Substring

    题目传送门 题意:训练指南P217 分析:没有模板串也就是在自动机上走L步,不走到val[u] == v的节点的概率 PS:边读边insert WA了,有毒啊! #include <bits/s ...

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

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

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

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

  5. UVA 11468 Substring (AC自动机)

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

  6. UVA 11468 Substring (记忆化搜索 + AC自动鸡)

    传送门 题意: 给你K个模式串, 然后,再给你 n 个字符, 和它们出现的概率 p[ i ], 模式串肯定由给定的字符组成. 且所有字符,要么是数字,要么是大小写字母. 问你生成一个长度为L的串,不包 ...

  7. Uva 11468 AC自动机或运算

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

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

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

  9. UVA - 11468:Substring

    随机生成一个字符可以看成在AC自动机里面向前走一个节点,那么ans就是0向前走L步并且不经过单词节点, 由概率知识可得,f[p][L]=∑f[nxt[p][i]][L-1]*g[i] 其中p表示位于p ...

随机推荐

  1. 如何使用PHP实现一个WebService

    WSDL WSDL(网络服务描述语言,Web Services Description Language)是一门基于 XML 的语言,用于描述 Web Services 以及如何对它们进行访问.这种文 ...

  2. dtp--eclipse的安装数据源管理的一个插件的安装方法

    1.  下载eclipse dtp 插件 http://download.eclipse.org/datatools/updates/1.11 help——>install new softwa ...

  3. java 串口通信 代码

    下面是我自己实现的串口接收的类,串口发送比较简单,就直接发送就可以了.下面的这个类可以直接使用. package com.boomdts.weather_monitor.util; import ja ...

  4. iOS开发--TableView详细解释

    -.建立 UITableView  DataTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)];  [Data ...

  5. AD15高版软件卡不卡,问题解决大讨论

    AD高版软件很卡(包括13 14 15版),这是我遇到过的问题,大家都遇到过的问题, 这里我分享一个解决办法:也请给位有什么好的方法也一起分享. 问题1卡:打开AD15软件, 按住鼠标中键 放大 或 ...

  6. C# Winform应用程序占用内存较大解决方法整理

     微软的 .NET FRAMEWORK 现在可谓如火如荼了.但是,.NET 一直所为人诟病的就是“胃口太大”,狂吃内存,虽然微软声称 GC 的功能和智能化都很高,但是内存的回收问题,一直存在困扰,尤其 ...

  7. 关于JavaScript中的setTimeout()链式调用和setInterval()探索

    http://www.cnblogs.com/Wenwang/archive/2012/01/06/2314283.html http://www.cnblogs.com/yangjunhua/arc ...

  8. 【原创】oracle的tpc-c测试及方法

    大家好,很高兴来到博客园分享自己的所见所得.希望和大家多多交流,共同进步. 本文重点在于简介使用BenchmarkSQL对oracle进行tpcc的测试步骤,只是一个简单入门的过程. 开源测试工具:B ...

  9. 安装TokuDB引擎

    前言:TokuDB 是一个高性能.支持事务处理的 MySQL 和 MariaDB 的存储引擎.TokuDB 的主要特点是高压缩比,高 INSERT 性能,支持大多数在线修改索引.添加字段,非常适合日志 ...

  10. 命令行下玩VC

    说明:(1)转载请注明出处:http://www.cnblogs.com/opangle/p/4298155.html (2)以下以VS2013为例,并假设VC安装路径为%VC_INSTALL_PAT ...