【HDU5955】Guessing the Dice Roll/马尔科夫
先从阿里机器学习算法岗网络笔试题说起:甲乙两人进行一个猜硬币的游戏。每个人有一个目标序列,由裁判来抛硬币。谁先得到裁判抛出的一串连续结果,谁赢。
甲的目标序列是正正正,乙的目标序列是反正正。那么如果裁判抛出了正正反正反正正....抛到第7个结果时乙胜,因为最后三个序列是“反正正”,而前面不存在甲的“正正正”序列。
问:甲的目标序列是????,乙的目标序列是????,求两人各自获胜的概率。
先说例子,正正正,反正正的概率。显然是1/8和7/8. 甲获胜的情况只有一种,就是三个连续的正,P = 1/8。为什么呢?因为,一旦裁判抛出一个“反”,结果就已经确定是乙胜了。所以甲要想获胜,只能从开头就是连着三个正。
那么对于一般题怎么做呢?
AC自动机 + 高斯消元。
你可以理解成 有限状态自动机+解方程。
(不好意思 这个图有误,所有曲线指的不应该是根节点,而应该是根节点读入"反"后的右节点)
根节点是开始,每抛出一个硬币走一条边。谁先走到最底下的点就胜。
到底部的获胜概率就是从开始局面到底部的期望次数。(到所有终点的期望和是1,等价于所有人的获胜概率和是1)
这么转换后就能做了。每个结点的期望 = 它前驱结点的期望 的 加权平均值。
如果只有一条边出去,那么它的下一个结点的期望显然就等于它的期望。
自环也算进去,加权算。
那么就能对每个结点列方程,n元一次方程。常数项在哪里?
在根节点前虚拟一个结点,指向根结点。虚拟结点的期望是1。
然后就能高斯消元做了!
以上的过程其实是一个 马尔科夫 过程。
我们解决了自动机到终点的概率(获胜概率,也就是到终点的期望次数),我们类似可以解决自动机走到终点的期望步数。也就是裁判期望抛多少回硬币游戏能够结束?
同样是列方程。
xi表示到i结点需要走的期望步数, xi = 1+∑ (pj*xj), (xj 是xi 的前驱结点, pj是xj结点走到到xi结点的概率)???
xi表示从i结点走到终点的期望步数, xi = 1+∑ (pj*xj), (xj 是xi 的后继结点, pj是xj结点走到到xi结点的概率)
以上。
扩展
如果你和一个人玩游戏,是否存在一种情况,无论对方的序列是什么序列,你都能够构造出一个 等长 的序列,使你的获胜概率比对方大?
答案是:当序列长度 > 2时,你总能使自己获胜概率更大。
详见 matrix67
现场赛的题是投骰子,谁先投出自己的序列谁胜。求各自获胜概率。
正解:ac自动机+高斯消元。
有一个做n遍消元的解法:对每个人的目标点消元。具体就是设xi为i结点到目标点的概率,dp算出根结点的值就是从根节点到目标点的概率。做n次即可。
还有一种有误差的解法。矩阵快速幂。矩阵的n次幂表示从根节点走n步到各个点的概率。n足够大时,就能近似表示出到各个点的概率。可惜,精度还是不够,误差比较大。。。。
还是要贴一下AC代码的。
#include <bits/stdc++.h>
#define gg puts("gg");
using namespace std;
const double eps = 1e-;
const int N = ;
int id(int c){
return c-;
}
struct Tire{
int nex[N][], fail[N], end[N];
int root, L;
int newnode(){
memset(nex[L], -, sizeof(nex[L]));
end[L] = ;
return L++;
}
void init(){
L = ;
root = newnode();
}
void insert(int* s, int l, int k){
int now = root;
for(int i = ; i < l; i++){
int p = id(s[i]);
if(nex[now][p] == -)
nex[now][p] = newnode();
now = nex[now][p];
}
end[now] = k;
}
void build(){
queue<int> Q;
fail[root] = root;
for(int i = ; i < ; i++){
int& u = nex[root][i];
if(u == -)
u = root;
else{
fail[u] = root;
Q.push(u);
}
}
while(!Q.empty()){
int now = Q.front();
Q.pop();
for(int i = ; i < ; i++){
int& u = nex[now][i];
if(u == -)
u = nex[ fail[now] ][i];
else{
fail[u] = nex[ fail[now] ][i];
end[u] |= end[ fail[u] ];
//last[u] = end[ fail[u] ]? fail[u] : last[ fail[u] ];
Q.push(u);
}
}
}
}
};
Tire ac; double a[][], x[], ans[];
int equ, var;
int Gauss(){
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]);
swap(x[k], x[max_r]);
}
x[k] /= a[k][col];
for(j = col+; j < var; j++) a[k][j] /= a[k][col];
a[k][col] = ;
for(i = ; i < equ; i++)
if(i != k){
x[i] -= x[k]*a[i][k];
for(j = col+; j < var; j++) a[i][j] -= a[k][j]*a[i][col];
a[i][col] = ;
}
}
return ;
} int s[];
int main(){
int n, l, t, ca = ; scanf("%d", &t);
while(t--){
ac.init();
scanf("%d%d", &n, &l);
for(int i = ; i <= n; i++){
for(int j = ; j < l; j++)
scanf("%d", s+j);
ac.insert(s, l, i);
}
ac.build(); memset(a, , sizeof(a));
memset(x, , sizeof(x));
equ = ac.L, var = ac.L;
for(int i = ; i < ac.L; i++)
a[i][i] = -;
x[] = -;
for(int i = ; i < ac.L; i++){
if(!ac.end[i])
for(int j = ; j < ; j++){
int to = ac.nex[i][j];
a[to][i] += 1.0/;
}
} Gauss(); for(int i = ; i < ac.L; i++)
if(ac.end[i]) ans[ ac.end[i] ] = x[i];
for(int i = ; i <= n; i++)
printf("%.6f%c", ans[i], " \n"[i == n]);
}
return ;
}
【HDU5955】Guessing the Dice Roll/马尔科夫的更多相关文章
- 隐马尔科夫模型python实现简单拼音输入法
在网上看到一篇关于隐马尔科夫模型的介绍,觉得简直不能再神奇,又在网上找到大神的一篇关于如何用隐马尔可夫模型实现中文拼音输入的博客,无奈大神没给可以运行的代码,只能纯手动网上找到了结巴分词的词库,根据此 ...
- 从随机过程到马尔科夫链蒙特卡洛方法(MCMC)
从随机过程到马尔科夫链蒙特卡洛方法 1. Introduction 第一次接触到 Markov Chain Monte Carlo (MCMC) 是在 theano 的 deep learning t ...
- HMM基本原理及其实现(隐马尔科夫模型)
HMM(隐马尔科夫模型)基本原理及其实现 HMM基本原理 Markov链:如果一个过程的“将来”仅依赖“现在”而不依赖“过去”,则此过程具有马尔可夫性,或称此过程为马尔可夫过程.马尔可夫链是时间和状态 ...
- 蒙特卡洛马尔科夫链(MCMC)
蒙特卡洛马尔科夫链(MCMC) 标签: 机器学习重要性采样MCMC蒙特卡洛 2016-12-30 20:34 3299人阅读 评论(0) 收藏 举报 分类: 数据挖掘与机器学习(41) 版权声明: ...
- Atitit 马尔可夫过程(Markov process) hmm隐马尔科夫。 马尔可夫链,的原理attilax总结
Atitit 马尔可夫过程(Markov process) hmm隐马尔科夫. 马尔可夫链,的原理attilax总结 1. 马尔可夫过程1 1.1. 马尔科夫的应用 生成一篇"看起来像文章的 ...
- 机器学习&数据挖掘笔记_19(PGM练习三:马尔科夫网络在OCR上的简单应用)
前言: 接着coursera课程:Probabilistic Graphical Models上的实验3,本次实验是利用马尔科夫网络(CRF模型)来完成单词的OCR识别,每个单词由多个字母组合,每个字 ...
- PRML读书会第八章 Graphical Models(贝叶斯网络,马尔科夫随机场)
主讲人 网神 (新浪微博: @豆角茄子麻酱凉面) 网神(66707180) 18:52:10 今天的内容主要是: 1.贝叶斯网络和马尔科夫随机场的概念,联合概率分解,条件独立表示:2.图的概率推断in ...
- 基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching)算法
文章目录 1. 1. 摘要 2. 2. Map-Matching(MM)问题 3. 3. 隐马尔科夫模型(HMM) 3.1. 3.1. HMM简述 3.2. 3.2. 基于HMM的Map-Matchi ...
- 隐马尔科夫模型HMM学习最佳范例
谷歌路过这个专门介绍HMM及其相关算法的主页:http://rrurl.cn/vAgKhh 里面图文并茂动感十足,写得通俗易懂,可以说是介绍HMM很好的范例了.一个名为52nlp的博主(google ...
随机推荐
- [转]MongoDB学习 C#驱动操作MongoDB
下载驱动 驱动的下载有两种方式:一种是在C#项目中通过NuGet进行安装,另一种是通过下面的链接:https://github.com/mongodb/mongo-csharp-driver/rele ...
- 基于XMPP协议(openfire服务器)的消息推送实现
转自:http://blog.csdn.net/nomousewch/article/details/8088277 最近好像有不少朋友关注Android客户端消息推送的实现,我在之前的项目中用到过J ...
- 临时存存储页面上的数据---js中的cookie
实现的效果: 当点击某个按钮的时候,实现点击A的同时,弹出B的注册div,使填写在B信息数据保存下来,点击B的确定按钮,B消失,A的图标往后移动一格,原来的位置为图标C,点击C可以弹出来一个链接的页面 ...
- Android (二维码)关于java.lang.UnsatisfiedLinkError的小案例
在许多项目中我们都会用到第三方动态库.so文件,但是往往会引来很多烦恼,比如:Java.lang.UnsatisfiedLinkError - ::-/com.ishow.scan E/Android ...
- 用soapUI生成客户端代码
一.用soapUI生成客户端代码 方法一: 1.第一步,打开soapUI,菜单栏里的tools,选择apache CXF,如图, 2.第二步,WSDL:写上你连接服务端的地址,OutputDirect ...
- [Android Tips] 15. Enforcing spaces in string resources
解决方案 使用双引号括起来 使用空格符的 unicode 编码 \u0200 ref Enforcing spaces in string resources How to put space cha ...
- zjuoj 3604 Tunnel Network
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3604 Tunnel Network Time Limit: 2 Secon ...
- GIt的命令
Git 命令 1,git init初始化当前文件夹为git仓库的根目录 2.git commit提交到本地仓库 3.git push origin master 提交到服务器 4.git log 查看 ...
- 【001:ubuntu下搭建ESP8266开发环境--编辑 编译 下载】
系统环境:ubuntu 16.04 TLS 64BIT 编辑器: Eclipse CDT 版本 编译器:xtensa-lx106-elf 交叉编译工具链 下载工具:esptool.py pyseria ...
- opencv的学习笔记4
通常更加高级的形态学变换,如开闭运算.形态学梯度.“顶帽”.“黑帽”等等,都是可以由常用的腐蚀膨胀技术结合来达到想要的效果. 1.开运算:先腐蚀后膨胀,用于用来消除小物体.在纤细点处分离物体.平滑较大 ...