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的更多相关文章

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

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

  2. HDU 5966 Guessing the Dice Roll

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

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

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

  4. 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 ...

  5. [HDU5955]Guessing the Dice Roll

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

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

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

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

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

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

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

  9. hdu 4586 Play the Dice 概率推导题

    A - Play the DiceTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/ ...

随机推荐

  1. 【个人使用.Net类库】(2)Log日志记录类

    开发接口程序时,要保证程序稳定运行就要时刻监控接口程序发送和接收的数据,这就需要一个日志记录的类将需要的信息记录在日志文件中,便于自己维护接口程序.(Web系统也是如此,只是对应的日志实现比这个要复杂 ...

  2. DropMaster

    DropMaster 是4个原生 VCL 控件的集合,在 Delphi 和 C++Builder 中使用.虽然包含在 Delphi 和 C++Builder 中的 VCL 组件允许同一程序内窗口之间的 ...

  3. RPI学习--webcam_用fswebcam抓取图片

    若 ls /dev 下没有video0,可以参考http://www.cnblogs.com/skynext/p/3644873.html,更新firmware 1,安装fswebcam: sudo ...

  4. linux之开发板与宿主机通信--ftp使用

    在目标板终端上输入命令: # ftp 192.16.77.66    //192.16.77.66是宿主机IP # cd /home/ //这里可以使用linux命令,但不能使有TAB键 # get ...

  5. Integer 和int

    获取Integer对象有两种方式:Integer x = 100:或者Integer x = new Integer(100): Integer x = 100:等价于Integer x = Inte ...

  6. python——周边

    Pythonic的禅意 import this python是用c语言写的.传说python不止有C语言实现,还有java实现,还有python实现的python,甚至还有js实现的python. p ...

  7. Codeforces Round #247 (Div. 2)

    A.水题. 遍历字符串对所给的对应数字求和即可. B.简单题. 对5个编号全排列,然后计算每种情况的高兴度,取最大值. C.dp. 设dp[n][is]表示对于k-trees边和等于n时,如果is== ...

  8. android avoiding-memory-leaks

    android avoiding-memory-leaks Memory Leak是会有多个方面会引起的,比如Drawable, RemoteViews, Receiver, Cursor,Input ...

  9. Xtreme Toolkit Pro 免费下载地址

    Xtreme Toolkit Pro 是针对Windows程序员的一套先进的用户界面套包,强大的功能可使您的应用程序具有专业的.现代感的外观. Xtreme Toolkit Pro 由8个专业级的构件 ...

  10. electronic data interchange 电子数据交换

    electronic data interchange 电子数据交换