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
 

 
对所有串建AC自动机,然后按照Trie图建立递推关系,转化成矩阵,用高斯消元解决带环的转移。
写起来略恶心,反正我是不想调了。
 

 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
#define reg register
inline int read() {
int res = ;char ch=getchar();bool fu=;
while(!isdigit(ch))fu|=(ch=='-'),ch=getchar();
while(isdigit(ch)) res=(res<<)+(res<<)+(ch^),ch=getchar();
return fu?-res:res;
} int T;
int n, L;
int nxt[][], fail[], danger[], tot, who[];
inline void ins(int *s, int id)
{
int now = ;
for (reg int i = ; i <= L ; i ++)
now = nxt[now][s[i]] ? nxt[now][s[i]] : nxt[now][s[i]] = ++tot;
danger[now] = ;
who[now] = id;
} inline void Build()
{
queue <int> q;
for (reg int i = ; i <= ;i ++) if (nxt[][i]) q.push(nxt[][i]);
while(!q.empty())
{
int x = q.front();q.pop();
for (reg int i = ; i <= ; i ++)
if (nxt[x][i]) fail[nxt[x][i]] = nxt[fail[x]][i], q.push(nxt[x][i]);
else nxt[x][i] = nxt[fail[x]][i];
danger[x] |= danger[fail[x]];
}
} long double a[][], ans[]; inline void Gauss()
{
for (reg int i = ; i <= tot ; i ++)
{
int k = i;
for (reg int j = i ; j <= tot ; j ++)
if (fabs(a[j][i]) > fabs(a[k][i])) k = j;
if (k != i) swap(a[k], a[i]);
for (reg int j = ; j <= tot ; j ++)
{
if (i == j) continue;
long double r = a[j][i] / a[i][i];
for (reg int k = i ; k <= tot + ; k ++)
a[j][k] -= a[i][k] * r;
}
}
} int main()
{
T = read();
while(T--)
{
memset(nxt, , sizeof nxt);
memset(fail, , sizeof fail);
memset(danger, , sizeof danger);
tot = ;
n = read(), L = read();
int tmp[];
for (reg int i = ; i <= n ; i ++)
{
for (reg int j = ; j <= L ; j ++) tmp[j] = read();
ins(tmp, i);
}
Build();
memset(a, , sizeof a);
for (reg int i = ; i <= tot ; i ++)
{
a[i][i] -= 1.0;
if (danger[i]) continue;
for (reg int j = ; j <= ; j ++)
a[nxt[i][j]][i] += 1.0 / 6.0;
}
a[][tot + ] = -1.0;
// for(int i=0;i<=tot;i++,puts(""))
// for(int j=0;j<=tot+1;j++) printf("%.2Lf ",a[i][j]);
Gauss();
for (reg int i = ; i <= tot ; i ++)
if (danger[i]) ans[who[i]] = a[i][tot + ] / a[i][i];
for (reg int i = ; i < n ; i ++) printf("%.6Lf ", ans[i]);
printf("%.6Lf\n", ans[n]);
}
return ;
}

[HDU5955]Guessing the Dice Roll的更多相关文章

  1. hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】

    含高斯消元模板 2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2 ...

  2. 【AC自动机】【高斯消元】hdu5955 Guessing the Dice Roll

    http://blog.csdn.net/viphong/article/details/53098489 我有一点不是很懂,这样算出来转移到AC自动机根节点的概率是一个远大于1的数. 按我的理解,因 ...

  3. HDU 5955 Guessing the Dice Roll

    HDU 5955 Guessing the Dice Roll 2016 ACM/ICPC 亚洲区沈阳站 题意 有\(N\le 10\)个人,每个猜一个长度为\(L \le 10\)的由\(1-6\) ...

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

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

  5. 【HDU5955】Guessing the Dice Roll/马尔科夫

    先从阿里机器学习算法岗网络笔试题说起:甲乙两人进行一个猜硬币的游戏.每个人有一个目标序列,由裁判来抛硬币.谁先得到裁判抛出的一串连续结果,谁赢. 甲的目标序列是正正正,乙的目标序列是反正正.那么如果裁 ...

  6. HDU 5966 Guessing the Dice Roll

    题意有 N≤10 个人,每个猜一个长度为L≤10的由1−6构成的序列,保证序列两两不同.不断地掷骰子,直到后缀与某人的序列匹配,则对应的人获胜.求每个人获胜的概率. 思路:建立trie图,跑高斯消元. ...

  7. 2016ACM/ICPC亚洲区沈阳站H - Guessing the Dice Roll HDU - 5955 ac自动机+概率dp+高斯消元

    http://acm.hdu.edu.cn/showproblem.php?pid=5955 题意:给你长度为l的n组数,每个数1-6,每次扔色子,问你每个串第一次被匹配的概率是多少 题解:先建成ac ...

  8. 【HDOJ5955】Guessing the Dice Roll(概率DP,AC自动机,高斯消元)

    题意: 有n个人,每个人有一个长为L的由1~6组成的数串,现在扔一个骰子,依次记录扔出的数字,如果当前扔出的最后L个数字与某个人的数串匹配,那么这个人就算获胜,现在问每个人获胜的概率是多少. n,l& ...

  9. LeetCode 1223. 掷骰子模拟 Dice Roll Simulation - Java - DP

    题目链接:1223. 掷骰子模拟 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数. 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[ ...

随机推荐

  1. Netty源码分析 (九)----- 拆包器的奥秘

    Netty 的解码器有很多种,比如基于长度的,基于分割符的,私有协议的.但是,总体的思路都是一致的. 拆包思路:当数据满足了 解码条件时,将其拆开.放到数组.然后发送到业务 handler 处理. 半 ...

  2. charles 重写工具/rewrite Srttings

    本文参考:charles 重写工具 rewrite Srttings 重写工具/rewrite Srttings and rewrite rule 功能:在通过charles时修改请求和响应 重写工具 ...

  3. 基于ViewPager与TabLayout建立三类图表

      延续昨天,今天使用ViewPager和TabLayout来实战一下,顺便补充一下新知识:   1.线形图,显示一周的温度情况.   2.饼状图,2017年互联网教育细分领域投资情况.   3.柱状 ...

  4. CentOS安装TeamViewer

    在https://www.teamviewer.com/en/download/linux/ 选择合适的host版本. wget https://download.teamviewer.com/dow ...

  5. 利用Python制作二维码

    利用简单的Python代码制作二维码 一.制作工具 安装Python环境 + PyCharm编译器. 二.电脑系统 本人win10 + Python3.7.0 + PyCharm. 三.写代码前先下载 ...

  6. eclipse与hadoop集成,运行wordCount1

    搭好了hadoop集群之后,就该使用它了 第一步:下载hadoop eclipse的插件,将它放到eclipse\plugins的目录下,然后重启eclipse,点击windows->show ...

  7. Creating a Store Locator with PHP, MySQL & Google Maps(保存地图坐标 经纬度方法 google mysql)

    Google Geo APIs Team August 2009 This tutorial is intended for developers who are familiar with PHP/ ...

  8. 最清晰的RESTFUL理解

    Restful理解 API(Application Programming Interface),顾名思义:是一组编程接口规范,客户端与服务端通过请求响应进行数据通信.REST(Representat ...

  9. [转] Julia 高性能动态编程语言入门

    本文共 851字,阅读大约需要 3分钟 ! 概 述 Julia 是一个 "全新"的高性能动态编程语言,前两天迎来了其 1.0 正式版的重大更新.Julia集 Python.C.R. ...

  10. Step ‘Publish JUnit test result report’ failed: No test report files were found问题解决

    1. 查看配置 2.路径设置错误,修改路径和path一致即可 修改后的测试报告路径 重新构建成功