含高斯消元模板

2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955

Guessing the Dice Roll

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1632    Accepted Submission(s): 480

Problem Description
There are N players playing a guessing game. Each player guesses a sequence consists of {1,2,3,4,5,6} with length L, then a dice will be rolled again and again and the roll out sequence will be recorded. The player whose guessing sequence first matches the last L rolls of the dice wins the game. 
Input
The first line is the number of test cases. For each test case, the first line contains 2 integers N (1 ≤ N ≤ 10) and L (1 ≤ L ≤ 10). Each of the following N lines contains a guessing sequence with length L. It is guaranteed that the guessing sequences are consist of {1,2,3,4,5,6} and all the guessing sequences are distinct.
Output
For each test case, output a line containing the winning probability of each player with the precision of 6 digits.
Sample Input
3 5 1 1 2 3 4 5 6 2 1 1 2 1 3 1 4 1 5 1 6 1 4 3 1 2 3 2 3 4 3 4 5 4 5 6
Sample Output
0.200000 0.200000 0.200000 0.200000 0.200000 0.027778 0.194444 0.194444 0.194444 0.194444 0.194444 0.285337 0.237781 0.237781 0.239102
Source
2016ACM/ICPC亚洲区沈阳站-重现赛(感谢东北大学)
Recommend
jiangzijing2015
题意:
有n个人猜掷骰子的序列。给定序列长度是l。只要n个人中的一个序列出现了,这个人就赢了游戏结束。问他们获胜的概率是多少。
思路:
没有想到是AC自动机。但是其实他本质就是在一个自动机的不同状态之间转转转,看最后转到哪个状态上去。
对这几个序列建立了AC自动机之后,就可以列出他们互相之间转移的概率方程了。然后解方程就可以得到每个人获胜的概率。
矩阵中的第\(j\)行表示的就是关于\(j\)这个状态的方程。\(a[j][i]\)表示由状态\(i\)转移到状态\(j\)的概率。
\(a[i][i]\)本身应该放在方程的右边,所以他是\(-1\)
根节点是比较特殊的,我们需要再设置一个虚拟节点,虚拟节点到根节点的概率是1,他也应该作为根节点初始时的概率放在右边。
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<set>
  9 using namespace std;
 10 typedef long long LL;
 11 #define N 100010
 12 #define pi 3.1415926535
 13
 14 int n, l, t;
 15 const int maxn = 105;
 16 struct trie{
 17     int son[7];
 18     int ed;
 19     int fail;
 20 }AC[maxn];
 21 int tot = 0;
 22 int fp[11];
 23
 24 void build(int s[], int id)
 25 {
 26     int now = 0;
 27     for(int i = 0; i < l; i++){
 28         if(AC[now].son[s[i]] == 0){
 29             AC[now].son[s[i]] = ++tot;
 30         }
 31         now = AC[now].son[s[i]];
 32     }
 33     AC[now].ed = id;
 34     fp[id] = now;
 35 }
 36
 37 void get_fail()
 38 {
 39     queue<int>que;
 40     for(int i = 1; i <= 6; i++){
 41         if(AC[0].son[i] != 0){
 42             AC[AC[0].son[i]].fail = 0;
 43             que.push(AC[0].son[i]);
 44         }
 45     }
 46
 47     while(!que.empty()){
 48         int u = que.front();
 49         que.pop();
 50         for(int i = 1; i <= 6; i++){
 51             if(AC[u].son[i] != 0){
 52                 AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
 53                 que.push(AC[u].son[i]);
 54             }
 55             else{
 56                 AC[u].son[i] = AC[AC[u].fail].son[i];
 57             }
 58         }
 59     }
 60 }
 61
 62 double a[maxn][maxn], x[maxn];
 63 const double eps = 1e-10;
 64 int equ, var;
 65 void gauss()
 66 {
 67     equ = var = tot + 1;
 68     int i,j,k,col,max_r;
 69     for(k=0,col=0;k<equ&&col<var;k++,col++)
 70     {
 71         max_r=k;
 72         for(i=k+1;i<equ;i++)
 73         {
 74             if(fabs(a[i][col] )>fabs(a[max_r][col] ) ) max_r=i;
 75         }
 76         if(fabs(a[max_r][col])<eps )  return;
 77         if(k!=max_r)
 78         {
 79             for(j=col;j<=var;j++)  swap(a[k][j],a[max_r][j]  );
 80         }
 81         for(j=col+1;j<=var;j++)  a[k][j]/=a[k][col];
 82
 83         a[k][col]=1;
 84
 85         for(i=0;i<equ;i++) if(i!=k)
 86         {
 87             for(j=col+1;j<=var;j++) a[i][j]-=a[k][j]*a[i][col];
 88
 89             a[i][col]=0;
 90         }
 91     }
 92     for(i=0;i<equ;i++)  x[i]=a[i][var];
 93     return;
 94 }
 95
 96 int main()
 97 {
 98     scanf("%d", &t);
 99     while(t--){
100         for(int i = 0; i <= tot; i++){
101             AC[i].fail = 0;
102             AC[i].ed = 0;
103             for(int j = 0; j < 7; j++){
104                 AC[i].son[j] = 0;
105             }
106         }
107         tot = 0;
108
109         scanf("%d%d", &n, &l);
110         for(int i = 1; i <= n; i++){
111             int tmp[11];
112             for(int j = 0; j < l; j++){
113                 scanf("%d", &tmp[j]);
114             }
115             build(tmp, i);
116         }
117         get_fail();
118
119         memset(a, 0, sizeof(a));
120         memset(x, 0, sizeof(x));
121         for(int i = 0; i <= tot; i++)a[i][i] = -1.0;
122         for(int i = 0; i <= tot; i++){
123             if(AC[i].ed == 0){
124                 for(int j = 1; j <= 6; j++){
125                     int to = AC[i].son[j];
126                     a[to][i] += 1.0 / 6;
127                 }
128             }
129
130         }
131
132         a[0][tot + 1] = -1.0;//虚拟节点
133         gauss();
134         for(int i = 1; i <= n; i++){
135             printf("%.6f", x[fp[i]]);
136             if(i == n){
137                 printf("\n");
138             }
139             else{
140                 printf(" ");
141             }
142         }
143
144         //cout<<"yes"<<endl;
145     }
146
147     return 0;
148 }

转载于:https://www.cnblogs.com/wyboooo/p/9951242.html

hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】相关推荐

  1. BZOJ 1444: [Jsoi2009]有趣的游戏 [AC自动机 高斯消元]

    1444: [Jsoi2009]有趣的游戏 题意:每种字母出现概率\(p_i\),有一些长度len的字符串,求他们出现的概率 套路DP的话,\(f[i][j]\) i个字符走到节点j的概率,建出转移矩 ...

  2. [高斯消元 概率 KMP] BZOJ 4820 [Sdoi2017]硬币游戏

    一个直观的想法 是建AC自动机 然后消元 但是这样变量个数是O(nm)O(nm) 然后我就不会做了 概率题都好妙啊 一个精妙的设计是再定义一个状态N 表示当前串不包含任何人的概率 举个例子 来自这里 ...

  3. bzoj4820 [Sdoi2017]硬币游戏 高斯消元+概率+kmp

    有环的概率是可以高斯消元的 由于匹配情况可能从一个串转移到另一个串,所以需要建一个转移关系的图 就可以建一个ac自动机,但节点数是nm的.就可以设未知数,然后凑一些方程. 设N表示没有任何人获胜的概率 ...

  4. BZOJ 1778: [Usaco2010 Hol]Dotp 驱逐猪猡 [高斯消元 概率DP]

    1778: [Usaco2010 Hol]Dotp 驱逐猪猡 题意:一个炸弹从1出发p/q的概率爆炸,否则等概率走向相邻的点.求在每个点爆炸的概率 高斯消元求不爆炸到达每个点的概率,然后在一个点爆炸就 ...

  5. bzoj1778 驱逐猪猡 [高斯消元+概率DP]

    Description 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N一共N个猪城.这些城市由M条由两个不同端点AjA_j和BjB_j (1≤Aj≤N;1≤Bj≤N)(1 \le A ...

  6. AC自动机 + 概率dp + 高斯消元 --- HDU 5955 or 2016年沈阳icpc H [AC自动机 + 概率dp + 高斯消元]详解

    题目链接 题目大意: 就是有NNN个人,每个人都会猜一个长度为LLL的只包含{1,2,3,4,5,6}\{1,2,3,4,5,6\}{1,2,3,4,5,6}的序列,现在裁判开始投掷骰子,并且把每次的 ...

  7. BZOJ.4820.[SDOI2017]硬币游戏(思路 高斯消元 哈希/AC自动机/KMP)

    BZOJ 洛谷 建出AC自动机,每个点向两个儿子连边,可以得到一张有向图.参照 [SDOI2012]走迷宫 可以得到一个\(Tarjan\)+高斯消元的\(O((nm)^3)\)的做法.(理论有\(6 ...

  8. 【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)

    [BZOJ4820][SDOI2017]硬币游戏(高斯消元) 题面 BZOJ 洛谷 题解 第一眼的感觉就是构\(AC\)自动机之后直接高斯消元算概率,这样子似乎就是\(BZOJ1444\)了.然而点数 ...

  9. 【SDOI2017】硬币游戏【KMP】【概率期望】【高斯消元】

    题意:给 nnn 个长度为 mmm 的 01 串,一个 01 串初始为空,不断随机一个字符加在后面,当出现给定的 nnn 个串中的一个时停止.分别求在 nnn 个串处停止的概率. 考场思路历程: 显然 ...

最新文章

  1. FFmpeg中一个线程获取视频流一个线程执行scale测试代码
  2. python有时候没有智能提示_python没有报错提示
  3. 【计算理论】计算复杂性 ( 证明 非确定性图灵机 与 确定性图灵机 的时间复杂度 之间的指数关系 )
  4. TCP/IP总结(4)TCP 之数据包格式
  5. linux内核剪裁 4412,itop4412开发板-Linux内核的编译
  6. java run 方法_java线程中的run()方法能有几个啊?
  7. Linux下Shell 备份脚本集合
  8. HDU2005 第几天?【日期计算】
  9. 如何让sublime编译c语言,如何在Sublime Text 3中编译C程序?
  10. 谷歌大脑2017总结下篇:Jeff Dean梳理6大领域研究
  11. 中颐软启动器说明书_中颐软启动器维修
  12. 怎么把PDF转换成图片?推荐6个终极解决方法!
  13. 回归平静是一种自我保护
  14. 【python】numpy库np.percentile详解
  15. Elastic:使用 ElastAlert 发送 Slack 通知
  16. SPSS—回归—多元线性回归(转)
  17. ubantu使用vsftp设置ftp上传 java添加系统用户限定ftp登录
  18. scratch之十大经典排序算法-冒泡排序法
  19. “个人知识管理”百科
  20. python贴吧发帖脚本-Python脚本实现自动发带图的微博

热门文章

  1. 遭遇ARP欺骗的处理办法
  2. 评价一个软件的3个角度
  3. pyhon取文件md5值
  4. OpenCV 直方图的计算和绘制
  5. C语言 递归实现辗转相除法 和 辗转相减法
  6. html ajax提交表单实例,Ajax提交表单并接收json实例代码
  7. 北交大计算机学院教授,北京交通大学计算机与信息技术学院研究生导师:鲁凌云...
  8. HTML DOM简介
  9. div居中与div内容居中,不一样
  10. python----python使用mysql