1444: [Jsoi2009]有趣的游戏

题意:每种字母出现概率\(p_i\),有一些长度len的字符串,求他们出现的概率


套路DP的话,\(f[i][j]\) i个字符走到节点j的概率,建出转移矩阵来矩乘几十次可以认为是无穷个字符,就得到概率了

但我们发现Trie图也是图啊,直接高斯消元就好了,\(f[i]\)表示走到节点i的期望次数

注意\(f[0]\)需要+1

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. using namespace std;
  7. typedef long long ll;
  8. const int N=105;
  9. const double eps=1e-8;
  10. inline int read(){
  11. char c=getchar();int x=0,f=1;
  12. while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
  13. while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
  14. return x*f;
  15. }
  16. int n, len, m, pos[N]; double p[N], x, y;
  17. char s[N];
  18. namespace ac{
  19. struct meow{int ch[11], fail, val;} t[N];
  20. int sz;
  21. void insert(char *s, int id) {
  22. int u=0;
  23. for(int i=1; i<=len; i++) {
  24. int c=s[i]-'A';
  25. if(!t[u].ch[c]) t[u].ch[c] = ++sz;
  26. u=t[u].ch[c];
  27. }
  28. t[u].val=1;
  29. pos[id]=u;
  30. }
  31. int q[N], head, tail;
  32. void build() {
  33. head=tail=1;
  34. for(int i=0; i<m; i++) if(t[0].ch[i]) q[tail++] = t[0].ch[i];
  35. while(head!=tail) {
  36. int u=q[head++];
  37. t[u].val |= t[t[u].fail].val;
  38. for(int i=0; i<m; i++) {
  39. int &v = t[u].ch[i];
  40. if(!v) v = t[t[u].fail].ch[i];
  41. else t[v].fail = t[t[u].fail].ch[i], q[tail++]=v;
  42. }
  43. }
  44. }
  45. }using ac::t; using ac::sz;
  46. double a[N][N];
  47. namespace eq{
  48. void build() {
  49. a[0][sz+1] = 1;
  50. for(int i=0; i<=sz; i++) { //printf("i %d\n",i);
  51. a[i][i]=1;
  52. if(!t[i].val) for(int j=0; j<m; j++)
  53. a[ t[i].ch[j] ][i] -= p[j];// printf("ch %d %lf %d\n",j,p[j],t[i].ch[j]);
  54. }
  55. //for(int i=0; i<=n; i++) for(int j=0; j<=n+1; j++) printf("%lf%c",a[i][j],j==n+1?'\n':' ');
  56. }
  57. void gauss(int n) {
  58. for(int i=0; i<=n; i++) {
  59. int r=i;
  60. for(int j=i; j<=n; j++) if(abs(a[j][i])>abs(a[r][i])) r=j;
  61. if(r!=i) for(int j=0; j<=n+1; j++) swap(a[r][j], a[i][j]);
  62. for(int k=i+1; k<=n; k++) {
  63. double t = a[k][i]/a[i][i];
  64. for(int j=i; j<=n+1; j++) a[k][j] -= t*a[i][j];
  65. }
  66. }
  67. for(int i=n; i>=0; i--) {
  68. for(int j=n; j>i; j--) a[i][n+1] -= a[i][j]*a[j][n+1];
  69. a[i][n+1] /= a[i][i];
  70. }
  71. }
  72. }
  73. int main() {
  74. freopen("in","r",stdin);
  75. n=read(); len=read(); m=read();
  76. int flag=0;
  77. for(int i=0; i<m; i++) x=read(), y=read(), p[i]=(double)x/y, flag |= p[i]>eps;
  78. if(!flag) {for(int i=1; i<=n; i++) puts("0.00"); return 0;}
  79. for(int i=1; i<=n; i++) scanf("%s",s+1), ac::insert(s, i);
  80. ac::build();
  81. eq::build(); eq::gauss(sz);
  82. //for(int i=1; i<=n; i++) printf("%d ",pos[i]); puts(" pos");
  83. for(int i=1; i<=n; i++) printf("%.2lf\n", a[pos[i]][sz+1]);
  84. }

BZOJ 1444: [Jsoi2009]有趣的游戏 [AC自动机 高斯消元]的更多相关文章

  1. BZOJ 1444 [Jsoi2009]有趣的游戏 (AC自动机 + 概率DP + Gauss)

    1444: [Jsoi2009]有趣的游戏 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1382  Solved: 498[Submit][Statu ...

  2. BZOJ 1444 [JSOI2009]有趣的游戏 (AC自动机、概率与期望DP、矩阵乘法)

    诶这题洛谷居然没有??? 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1444 题解: 我见到主要有三种做法. 一是矩阵乘法.设\(d ...

  3. BZOJ 1444: [Jsoi2009]有趣的游戏 AC自动机+概率与期望+矩阵乘法

    这道题还比较友好~首先,构建出来 $AC$ 自动机,那么我们要求的就是从 $0$ 号点走无限次走到一个终止节点的概率. 考虑构建转移矩阵 $M,$ $M_{i,j}$ 表示节点 $i$ 转移到节点 $ ...

  4. BZOJ 1444:[JSOI2009]有趣的游戏

    BZOJ 1444:[JSOI2009]有趣的游戏 题目链接 首先我们建出Trie图,然后高斯消元. 我们设\(f_i\)表示经过第\(i\)个点的期望次数: \[ f_x=\sum i\cdot p ...

  5. hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】

    hdu 5955 Guessing the Dice Roll [AC自动机+高斯消元] 题意:给出 n≤10 个长为 L≤10 的串,每次丢一个骰子,先出现的串赢,问获胜概率. 题解:裸的AC自动机 ...

  6. BZOJ:4820: [Sdoi2017]硬币游戏&&BZOJ:1444: [Jsoi2009]有趣的游戏(高斯消元求概率)

    1444: [Jsoi2009]有趣的游戏 4820: [Sdoi2017]硬币游戏 这两道题都是关于不断随机生成字符后求出现给定字符串的概率的问题. 第一题数据范围较小,将串建成AC自动机以后,以A ...

  7. bzoj 1444: [Jsoi2009]有趣的游戏【AC自动机+dp+高斯消元】

    https://blog.sengxian.com/solutions/bzoj-1444 orz 一直是我想错了,建出AC自动机之后,实际上这个定义是设f[i]为经过i节点的 * 期望次数 * ,因 ...

  8. 【BZOJ1444】[Jsoi2009]有趣的游戏 AC自动机+概率DP+矩阵乘法

    [BZOJ1444][Jsoi2009]有趣的游戏 Description Input 注意 是0<=P Output Sample Input Sample Output HINT  30%的 ...

  9. ●BZOJ 1444 [Jsoi2009]有趣的游戏

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1444题解.1: 概率dp,矩阵乘法,快速幂. 对所有串建立AC自动机, 那么如果在trie树 ...

随机推荐

  1. Centos7安装和卸载Mongodb数据库

    MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非 ...

  2. android仿漫画源码、抽奖转盘、Google相册、动画源码等

    Android精选源码 android实现仿今日头条的开源项目 波浪效果,实现流量的动态显示 美妆领域的app, 集成了摄像头取色, 朋友圈, 滤镜等 android仿漫画源码 android一个视差 ...

  3. Centos7安装docker-compse踩过的坑

    一.概要 ​ 本文,我们介绍如何在centos7环境下安装docker-compose, 记录下安装过程步骤以及遇到的问题还有解决办法. 二.安装方式 1.官方安装方式 sudo curl -L ht ...

  4. JavaScript八张思维导图—数组用法

    JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...

  5. thinkphp5使用redis实现秒杀商品活动

    如题,废话少说贴码为上↓ // 初始化redis数据列表 模拟库存50,redis搭建在centos中已开启 public function redisinit(){ $store=50; // 库存 ...

  6. 用PHP,怎么获取PHP.ini中的文件上传最大的字节数。也就是默认的2M

    PHP中用ini_get函数来获取服务器允许的文件上传最大字节数,如:

  7. 邓_phpcms_二次开发_创建插件

    Phpcms_V9           [test]测试 ================================================================ ====== ...

  8. 月薪20k以上的高级程序员需要学习哪些技术呢?

    课程内容: 源码分析.分布式架构.微服务架构.性能优化.团队协作效率.双十一项目实战 适用对象: 1-5年或更长软件开发经验,没有工作经验但基础非常扎实,对java工作机制,常用设计思想,常用java ...

  9. Java进阶篇(四)——Java异常处理

    程序中总是存在着各种问题,为了使在程序执行过程中能正常运行,使用Java提供的异常处理机制捕获可能发生的异常,对异常进行处理并使程序能正常运行.这就是Java的异常处理. 一.可捕获的异常 Java中 ...

  10. es6重点笔记:Symbol,Set,Map,Proxy,Reflect

    一,Symbol 原始数据类型,不是对象,它是JavaScript第七种数据类型,表示独一无二的值.Symbol是通过Symbol函数生成的: let s = Symbol(); typeof s / ...