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. jmeter运行第三方java项目

    自己写了个简化系统操作的小工具,因为不想给别人用的时候占用本地资源于是写的是纯java项目,后面放到jmeter中通过beanshell sampler调用. java源码不贴了,把写好的项目导出成可 ...

  2. 【linux】【jenkins】自动化运维六 构建生成备份

    push tag用于提交代码构建成功后push tag,以防提交代码报错,方便回滚之前正常的代码. 由于采用docker部署的形式,构建失败自动回滚还未实现,待研究解决. 构建后操作选择 Git Pu ...

  3. docker部署jenkins

    步骤一: 查找jenkins镜像(也可以直接去jenkins官网找镜像docker pull jenkins/jenkins)(官方版本文档https://hub.docker.com/_/jenki ...

  4. Xshell无法连接Linux虚拟机问题

    遇到的情况是,在虚拟机下安装了Linux后,xshell无法连接远程的虚拟机. 我遇到的情况是虚拟机可以ping 主机,主机确ping不了虚拟机. 使用的VM设置了两个网卡,一个nat  一个host ...

  5. .NetCore技术研究-一套代码同时支持.NET Framework和.NET Core

    在.NET Core的迁移过程中,我们将原有的.NET Framework代码迁移到.NET Core.如果线上只有一个小型的应用还好,迁移升级完成后,只需要维护.NET Core这个版本的代码. 但 ...

  6. Spring boot 梳理 - WebMvcConfigurer接口 使用案例

    转:https://yq.aliyun.com/articles/617307 SpringBoot 确实为我们做了很多事情, 但有时候我们想要自己定义一些Handler,Interceptor,Vi ...

  7. RedHat安装git报错 expected specifier-qualifier-list before ‘z_stream’

    年初开学的时候认识到了git,因为当时也没装虚拟机甚至是不知道虚拟机这个东西,所以就下载了Windows下的git.当时跟着廖雪峰Git教程 学了几个命令.安装了虚拟机,也学了linux的基本命令后, ...

  8. Open Source v.s. Open Core

    摘要 本文翻译自 CMSWire 网站的<Open Source vs. Open Core: What's the Difference?>,主要介绍 Open Source 和 Ope ...

  9. Cocos Creator 通用框架设计 —— 网络

    在Creator中发起一个http请求是比较简单的,但很多游戏希望能够和服务器之间保持长连接,以便服务端能够主动向客户端推送消息,而非总是由客户端发起请求,对于实时性要求较高的游戏更是如此.这里我们会 ...

  10. c语言作业04

    这个作业属于哪个课程 C语言程序设计Ⅱ 这个作业要求在哪里 (作业要求)[https://edu.cnblogs.com/campus/zswxy/SE2019-1/homework/9773] 我在 ...