HDU 5955 Guessing the Dice Roll
HDU 5955 Guessing the Dice Roll
2016 ACM/ICPC 亚洲区沈阳站
题意
- 有\(N\le 10\)个人,每个猜一个长度为\(L \le 10\)的由\(1-6\)构成的序列,保证序列两两不同。
- 不断地掷骰子,直到后缀与某人的序列匹配,则对应的人获胜。
- 求每个人获胜的概率。
思路
- 显然,涉及的序列最多100个,用ac自动机构出这些状态,计算状态之间的转移概率。
- 记增量矩阵为\(A\)(即终状态不再计算转移到自身的概率),答案为\(b\),初始序列为\(x\),则$$b=\sum_{i=1}{\infty}{Ai}x$$
- 显然矩阵\(A\)是收敛的,所以式子转化为$$b=(I-A)^{-1}x\x=(I-A)b$$
- 高斯消元求解即可,注意精度问题。
- 另一种解法,构造包括终止状态转移到自身的矩阵,结合快速幂,可以卡过去(注意指数取\(2^i\)形式以减少常数)。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define sz(x) ((int)(x).size())
#define rep(i,l,r) for(int i=(l);i<(r);++i)
//-------head-------
const int N = 1007;
const double EPS = 1e-12;
int n, l, a[N], id[N];
template<int V>
struct AhoCorasick {
int dep[V];
int siz, lnk[V], que[V], trie[V][7];
int addNode(int _dep) {
memset(trie[siz], 0, sizeof(trie[siz]));
lnk[siz] = 0, dep[siz] = _dep;
return siz++;
}
void init() {
siz = 0;
addNode(0);
}
int add(const int *a, int n) {
int p = 0;
rep(i, 0, n)
{
int x = a[i];
if (!trie[p][x])
trie[p][x] = addNode(i + 1);
p = trie[p][x];
}
return p;
}
void build() {
que[0] = 0;
for (int h = 0, t = 1; h < t; ++h) {
int v = que[h];
rep(c, 1, 7)
if (trie[v][c]) {
int u = lnk[v];
while (u && !trie[u][c])
u = lnk[u];
lnk[trie[v][c]] = !v ? 0 : trie[u][c];
que[t++] = trie[v][c];
} else {
trie[v][c] = trie[lnk[v]][c];
}
}
}
};
template<int N>
struct Gauss {
double a[N][N];
void init(int n, int m) {
rep(i, 0, n)
rep(j, 0, m)
a[i][j] = 0;
}
void run(int n, int m) {
int row, col;
for (row = col = 0; row < n && col < m; ++row, ++col) {
int mxr = row;
rep(i, row + 1, n)
if (fabs(a[i][col]) > fabs(a[mxr][col]))
mxr = i;
if (fabs(a[mxr][col]) < EPS) {
--row;
continue;
}
if (mxr != row)
swap(a[row], a[mxr]), swap(id[row], id[mxr]);
rep(i, 0, n)
if (i != row && fabs(a[i][col]) > EPS)
for (int j = m; j >= col; --j)
a[i][j] -= a[row][j] * a[i][col] / a[row][col];
}
}
void out(int n, int m) {
rep(i, 0, n) {
rep(j, 0, m)
printf("%lf ", a[i][j]);
puts("");
}
}
};
AhoCorasick<N> ac;
Gauss<N> ga;
double ans[N];
int main() {
int T;
scanf("%d", &T);
rep(cas, 0, T) {
scanf("%d%d", &n, &l);
ac.init();
memset(id, -1, sizeof(id));
rep(i, 0, n) {
rep(j, 0, l)
scanf("%d", &a[j]);
id[ac.add(a, l)] = i;
}
ac.build();
ga.init(ac.siz, ac.siz + 1);
rep(i, 0, ac.siz) {
if (~id[i]) {
// ga.a[i][i] = 0;
} else {
rep(j, 1, 7)
ga.a[ac.trie[i][j]][i] += 1.0 / 6.0 ;
}
}
rep(i, 0, ac.siz)
ga.a[i][i] -= 1.0;
ga.a[0][ac.siz] = -1.0;
// ga.out(ac.siz, ac.siz + 1);
ga.run(ac.siz, ac.siz);
// puts("");
// ga.out(ac.siz, ac.siz + 1);
rep(i, 0, ac.siz)
if (~id[i]) {
ans[id[i]] = ga.a[i][ac.siz] / ga.a[i][i];
}
rep(i, 0, n) {
if (i)
putchar(' ');
printf("%.6lf", fabs(ans[i]));
}
puts("");
}
return 0;
}
HDU 5955 Guessing the Dice Roll的更多相关文章
- hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】
hdu 5955 Guessing the Dice Roll [AC自动机+高斯消元] 题意:给出 n≤10 个长为 L≤10 的串,每次丢一个骰子,先出现的串赢,问获胜概率. 题解:裸的AC自动机 ...
- HDU 5966 Guessing the Dice Roll
题意有 N≤10 个人,每个猜一个长度为L≤10的由1−6构成的序列,保证序列两两不同.不断地掷骰子,直到后缀与某人的序列匹配,则对应的人获胜.求每个人获胜的概率. 思路:建立trie图,跑高斯消元. ...
- hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】
含高斯消元模板 2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2 ...
- 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 ...
- [HDU5955]Guessing the Dice Roll
Problem Description There are N players playing a guessing game. Each player guesses a sequence cons ...
- 【HDU5955】Guessing the Dice Roll/马尔科夫
先从阿里机器学习算法岗网络笔试题说起:甲乙两人进行一个猜硬币的游戏.每个人有一个目标序列,由裁判来抛硬币.谁先得到裁判抛出的一串连续结果,谁赢. 甲的目标序列是正正正,乙的目标序列是反正正.那么如果裁 ...
- 【AC自动机】【高斯消元】hdu5955 Guessing the Dice Roll
http://blog.csdn.net/viphong/article/details/53098489 我有一点不是很懂,这样算出来转移到AC自动机根节点的概率是一个远大于1的数. 按我的理解,因 ...
- 【HDOJ5955】Guessing the Dice Roll(概率DP,AC自动机,高斯消元)
题意: 有n个人,每个人有一个长为L的由1~6组成的数串,现在扔一个骰子,依次记录扔出的数字,如果当前扔出的最后L个数字与某个人的数串匹配,那么这个人就算获胜,现在问每个人获胜的概率是多少. n,l& ...
- hdu 4586 Play the Dice 概率推导题
A - Play the DiceTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/ ...
随机推荐
- SPOJ COT2 树上找路径上不同值的个数
题目大意 给出多个询问u , v , 求出u-v路径上点权值不同的个数 开始做的是COT1,用主席树写过了,理解起来不难 很高兴的跑去做第二道,完全跟普通数组区间求k个不同有很大区别,完全没思路 膜拜 ...
- 推荐一款好用轻便的在线UML画图工具
刚接触UML时间不长,看了N多教学视频,下载好了几个软件各种不习惯 当我遇见了ProcessOn 从此我彻底“爱上”了它! http://www.processon.com/ UML各类例图它几乎全 ...
- 【转发】linux yum命令详解
linux yum命令详解 yum(全 称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器.基於RPM包管理, ...
- RAD,V模型
介绍: RAD(Rap Application Developmen快速应用开发t)模型是软件开发过程中的一个重要模型,由于模型构图类似字母V,所以又称为软件开发的V模型.它通过开发和测试同时进行的方 ...
- Visual Studio 2013 如何关闭调试而不关闭IIS Express
在VS主面板打开:工具->选项->调试->编辑继续 取消选中[启用"编辑并继续"] 就OK了 (英文版的请对应相应的操作) 不过这是针对所有的调试,如果你想针 ...
- setLayoutParams getLayoutParams
继承关系:java.lang.Object ↳ android.view.ViewGroup.LayoutParams ↳ android.view.ViewGroup.MarginLayoutPar ...
- Android Studio开发环境变量配置
1,Android Studio官网可以下载 可以选择下载带有SDK版本 2,如果没有配置SDK,AVD虚拟机是没法使用的,真机调试也用不了. 有时会提醒adb is not connected. 和 ...
- WebGrid Enterprise免费下载
WebGrid.NET Enterprise是一个为ASP.NET平台下WEB开发而设计的高级数据表格控件.WebGrid.NET为复杂的分层次导航交互式企业级信息传输提供了全面而先进的功能,它允许用 ...
- 转载:socket.io 入门
原文链接:http://cnodejs.org/topic/50a1fcc7637ffa4155b5a264 我自己在用socket.io开发,对官方网站上的文档,进行简单的整理,然后自己写了一个简单 ...
- Python的文件类型
Python的文件类型主要分为3种:源代码(source file).字节码(byte-code file).优化的字节码(optimized file).这些代码都可以直接运行,不需要编译或者连接. ...