含高斯消元模板

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
 
Recommend
jiangzijing2015
 
 
 
题意:
有n个人猜掷骰子的序列。给定序列长度是l。只要n个人中的一个序列出现了,这个人就赢了游戏结束。问他们获胜的概率是多少。
思路:
没有想到是AC自动机。但是其实他本质就是在一个自动机的不同状态之间转转转,看最后转到哪个状态上去。
对这几个序列建立了AC自动机之后,就可以列出他们互相之间转移的概率方程了。然后解方程就可以得到每个人获胜的概率。
矩阵中的第\(j\)行表示的就是关于\(j\)这个状态的方程。\(a[j][i]\)表示由状态\(i\)转移到状态\(j\)的概率。
\(a[i][i]\)本身应该放在方程的右边,所以他是\(-1\)
根节点是比较特殊的,我们需要再设置一个虚拟节点,虚拟节点到根节点的概率是1,他也应该作为根节点初始时的概率放在右边。
 #include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
typedef long long LL;
#define N 100010
#define pi 3.1415926535 int n, l, t;
const int maxn = ;
struct trie{
int son[];
int ed;
int fail;
}AC[maxn];
int tot = ;
int fp[]; void build(int s[], int id)
{
int now = ;
for(int i = ; i < l; i++){
if(AC[now].son[s[i]] == ){
AC[now].son[s[i]] = ++tot;
}
now = AC[now].son[s[i]];
}
AC[now].ed = id;
fp[id] = now;
} void get_fail()
{
queue<int>que;
for(int i = ; i <= ; i++){
if(AC[].son[i] != ){
AC[AC[].son[i]].fail = ;
que.push(AC[].son[i]);
}
} while(!que.empty()){
int u = que.front();
que.pop();
for(int i = ; i <= ; i++){
if(AC[u].son[i] != ){
AC[AC[u].son[i]].fail = AC[AC[u].fail].son[i];
que.push(AC[u].son[i]);
}
else{
AC[u].son[i] = AC[AC[u].fail].son[i];
}
}
}
} double a[maxn][maxn], x[maxn];
const double eps = 1e-;
int equ, var;
void gauss()
{
equ = var = tot + ;
int i,j,k,col,max_r;
for(k=,col=;k<equ&&col<var;k++,col++)
{
max_r=k;
for(i=k+;i<equ;i++)
{
if(fabs(a[i][col] )>fabs(a[max_r][col] ) ) max_r=i;
}
if(fabs(a[max_r][col])<eps ) return;
if(k!=max_r)
{
for(j=col;j<=var;j++) swap(a[k][j],a[max_r][j] );
}
for(j=col+;j<=var;j++) a[k][j]/=a[k][col]; a[k][col]=; for(i=;i<equ;i++) if(i!=k)
{
for(j=col+;j<=var;j++) a[i][j]-=a[k][j]*a[i][col]; a[i][col]=;
}
}
for(i=;i<equ;i++) x[i]=a[i][var];
return;
} int main()
{
scanf("%d", &t);
while(t--){
for(int i = ; i <= tot; i++){
AC[i].fail = ;
AC[i].ed = ;
for(int j = ; j < ; j++){
AC[i].son[j] = ;
}
}
tot = ; scanf("%d%d", &n, &l);
for(int i = ; i <= n; i++){
int tmp[];
for(int j = ; j < l; j++){
scanf("%d", &tmp[j]);
}
build(tmp, i);
}
get_fail(); memset(a, , sizeof(a));
memset(x, , sizeof(x));
for(int i = ; i <= tot; i++)a[i][i] = -1.0;
for(int i = ; i <= tot; i++){
if(AC[i].ed == ){
for(int j = ; j <= ; j++){
int to = AC[i].son[j];
a[to][i] += 1.0 / ;
}
} } a[][tot + ] = -1.0;//虚拟节点
gauss();
for(int i = ; i <= n; i++){
printf("%.6f", x[fp[i]]);
if(i == n){
printf("\n");
}
else{
printf(" ");
}
} //cout<<"yes"<<endl;
} return ;
}

hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】的更多相关文章

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

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

  2. UVALive - 3490 Generator (AC自动机+高斯消元dp)

    初始有一个空串s,从前n个大写字母中不断随机取出一个字母添加到s的结尾,出现模式串t时停止,求停止时s的长度期望. 这道题解法不唯一,比较无脑的方法是对模式串t建一个单串AC自动机,设u为自动机上的一 ...

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

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

  4. [HDU5955]Guessing the Dice Roll

    Problem Description There are N players playing a guessing game. Each player guesses a sequence cons ...

  5. [JLOI2012]时间流逝 树上高斯消元 概率期望

    题面 题意:(感觉题面写的题意是错的?)有\(n\)种能量不同的圈,设当前拥有的圈的集合为\(S\),则: 1,每天有\(p\)概率失去一个能量最小的圈.特别的,如果\(S = \varnothing ...

  6. 【BZOJ-3143】游走 高斯消元 + 概率期望

    3143: [Hnoi2013]游走 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2264  Solved: 987[Submit][Status] ...

  7. 【BZOJ-3270】博物馆 高斯消元 + 概率期望

    3270: 博物馆 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 292  Solved: 158[Submit][Status][Discuss] ...

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

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

  9. BZOJ 2337: [HNOI2011]XOR和路径 [高斯消元 概率DP]

    2337: [HNOI2011]XOR和路径 题意:一个边权无向连通图,每次等概率走向相连的点,求1到n的边权期望异或和 这道题和之前做过的高斯消元解方程组DP的题目不一样的是要求期望异或和,期望之间 ...

随机推荐

  1. [Arch] 03. Practice UML in project

    参考列表: 搜索:跟我学UML建模工具StarUML 系列文章 第一部分,下载和安装及破解StarUML工具软件 第二部分,StarUML工具软件的主要功能界面和UML图的创建示例 [Design P ...

  2. 用XYNTService把Python程序变为服务

    1. XYNTService的使用 1.1. 介绍 1.2. XYNTService 2. 用XYNTService把Python程序变为服务 1. XYNTService的使用 1.1. 介绍 通常 ...

  3. vsftpd下错误之:500 OOPS

    vsftpd下错误之:500 OOPS.vsftpd 是在Linux发行版中最推崇的一种FTP服务器程序,vsftpd的特点:小巧轻快.安全易用等. Linux也是为人们所常用的操作系统之一.这里主要 ...

  4. HTML5和CSS3扁平化风格博客(进阶篇)

    趁热打铁,将剩下的部分完结~ 接上篇,增加了一些js特效:侧边栏,返回顶部. 至于效果,也不知道gif的图片怎么显示不上去了 无奈只能直接上代码了,完整版请点击: https://files.cnbl ...

  5. java基础思维导图大全

  6. Android学习之Dialog

    在Android开发中,我们经常会需要在Android界面上弹出一些对话框,比如询问用户或者让用户选择.这些功能我们叫它Android Dialog对话框; 实例如下: 1.效果图: 2.XML代码: ...

  7. PHP 二叉树 二叉排序树实现

    <?php /** * PHP 二叉树 * @author : xiaojiang 2014-01-01 * */ class Tree { protected $k = null; prote ...

  8. 脚本学习 game.sh

    #!/bin/bash #game_error.sh ]]; then #$#表示参数个数 -lt小于 echo "Usage: game_error.sh time[20170710]&q ...

  9. JAVA知多少

    读<java解惑>感觉有意思的就记录一下. 1.判断奇数还是偶数 public boolean isOdd(int i){ return i%2==1; }; 这样子看起来很对,但是考虑到 ...

  10. Esper学习之十二:EPL语法(八)

    今天的内容十分重要,在Esper的应用中是十分常用的功能之一.它是一种事件集合,我们可以对这个集合进行增删查改,所以在复杂的业务场景中我们肯定不会缺少它.它就是Named Window. 由于本篇篇幅 ...