【HDOJ5955】Guessing the Dice Roll(概率DP,AC自动机,高斯消元)
题意:
有n个人,每个人有一个长为L的由1~6组成的数串,现在扔一个骰子,依次记录扔出的数字,如果当前扔出的最后L个数字与某个人的数串匹配,那么这个人就算获胜,现在问每个人获胜的概率是多少。
n,l<=10
思路:对于无限型的概率
首先显然有一个暴力做法是对于n个串建出AC自动机和转移矩阵后跑若干次矩乘快速幂DP使得答案趋于稳定后可以将结果看做答案
正解是高斯消元
每个点对于它的后继有1/6的概率跑到,计算贡献后累加
边界条件:题目给出的n个串没有后继
游戏开始时必定会转移到根节点,等价于有一个虚的节点(不需要建立方程)对根有100%的1的贡献
剩下的就是高斯消元模板了
- #include<cstdio>
- #include<cstring>
- #include<string>
- #include<cmath>
- #include<iostream>
- #include<algorithm>
- #include<map>
- #include<set>
- #include<queue>
- #include<vector>
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- typedef unsigned int uint;
- typedef unsigned long long ull;
- typedef pair<int,int> PII;
- typedef vector<int> VI;
- #define fi first
- #define se second
- #define MP make_pair
- #define N 11000
- #define M 210
- #define MOD 1000000007
- #define eps 1e-8
- #define pi acos(-1)
- double a[M][M];
- int nxt[M][],fa[M],c[M],d[N],q[N],b[N],flag[N],n,l,cnt;
- int read()
- {
- int v=,f=;
- char c=getchar();
- while(c<||<c) {if(c=='-') f=-; c=getchar();}
- while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
- return v*f;
- }
- void build(int k)
- {
- int u=;
- for(int i=;i<=l;i++)
- {
- if(!nxt[u][b[i]]) nxt[u][b[i]]=++cnt;
- u=nxt[u][b[i]];
- }
- c[k]=u;
- d[u]=k;
- }
- void acauto()
- {
- int t=; int w=; q[]=;
- while(t<w)
- {
- int u=q[++t];
- // printf("%d\n",u);
- for(int i=;i<=;i++)
- {
- if(nxt[u][i])
- {
- int son=nxt[u][i];
- int p=fa[u];
- if(u==) fa[son]=;
- else fa[son]=nxt[p][i];
- q[++w]=son;
- }
- else
- {
- int p=fa[u];
- if(u==) nxt[u][i]=;
- else nxt[u][i]=nxt[p][i];
- }
- }
- }
- }
- void init()
- {
- /* for(int i=1;i<=cnt;i++)
- {
- fa[i]=flag[i]=d[i]=0;
- for(int j=1;i<=6;j++) nxt[i][j]=0;
- }
- memset(q,0,sizeof(q));
- for(int i=1;i<=cnt;i++)
- for(int j=0;j<=cnt;j++) a[i][j]=0;
- for(int i=1;i<=n;i++) c[i]=0;*/
- memset(a,,sizeof(a));
- memset(nxt,,sizeof(nxt));
- memset(fa,,sizeof(fa));
- memset(c,,sizeof(c));
- memset(d,,sizeof(d));
- //memset(q,0,sizeof(q));
- memset(b,,sizeof(b));
- cnt=;
- }
- void test()
- {
- for(int i=;i<=cnt;i++)
- {
- for(int j=;j<=cnt+;j++) printf("%.2lf ",a[i][j]);
- printf("\n");
- }
- printf("\n");
- }
- int main()
- {
- freopen("hdoj5955.in","r",stdin);
- freopen("hdoj5955.out","w",stdout);
- int cas;
- scanf("%d",&cas);
- while(cas--)
- {
- init();
- scanf("%d%d",&n,&l);
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=l;j++) scanf("%d",&b[j]);
- build(i);
- }
- acauto();
- for(int i=;i<=cnt;i++)
- {
- a[i][cnt+]=;
- a[i][i]=-1.0;
- if(d[i]) continue;
- for(int j=;j<=;j++)
- {
- int v=nxt[i][j];
- a[v][i]+=1.0/6.0;
- // printf("%d %d\n",i,v);
- }
- }
- a[][cnt+]=-1.0;
- // test();
- for(int i=;i<=cnt;i++)
- {
- int K=i;
- for(int j=i+;j<=cnt;j++)
- if(fabs(a[j][i])>fabs(a[K][i])) K=j;
- if(K!=i)
- for(int j=;j<=cnt+;j++) swap(a[i][j],a[K][j]);
- for(int j=i+;j<=cnt;j++)
- {
- double f=a[j][i]/a[i][i];
- for(int k=i;k<=cnt+;k++) a[j][k]-=f*a[i][k];
- }
- }
- for(int i=cnt;i>=;i--)
- {
- for(int j=i+;j<=cnt;j++)
- a[i][cnt+]-=a[i][j]*a[j][cnt+];
- a[i][cnt+]=a[i][cnt+]/a[i][i];
- }
- // test();
- for(int i=;i<=n;i++)
- if(i<n) printf("%.6lf ",a[c[i]][cnt+]);
- else printf("%.6lf\n",a[c[i]][cnt+]);
- }
- return ;
- }
【HDOJ5955】Guessing the Dice Roll(概率DP,AC自动机,高斯消元)的更多相关文章
- hdu 5955 Guessing the Dice Roll 【AC自动机+高斯消元】
hdu 5955 Guessing the Dice Roll [AC自动机+高斯消元] 题意:给出 n≤10 个长为 L≤10 的串,每次丢一个骰子,先出现的串赢,问获胜概率. 题解:裸的AC自动机 ...
- 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 ...
- BZOJ3270: 博物馆【概率DP】【高斯消元】
Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博物馆.这座博物馆有着特别的样式.它包含由m条走廊连接的n间房间,并且满足可以从任何一 ...
- BZOJ3141 Hnoi2013 游走 【概率DP】【高斯消元】*
BZOJ3141 Hnoi2013 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点 ...
- UVALive - 3490 Generator (AC自动机+高斯消元dp)
初始有一个空串s,从前n个大写字母中不断随机取出一个字母添加到s的结尾,出现模式串t时停止,求停止时s的长度期望. 这道题解法不唯一,比较无脑的方法是对模式串t建一个单串AC自动机,设u为自动机上的一 ...
- BZOJ 1444: [Jsoi2009]有趣的游戏 [AC自动机 高斯消元]
1444: [Jsoi2009]有趣的游戏 题意:每种字母出现概率\(p_i\),有一些长度len的字符串,求他们出现的概率 套路DP的话,\(f[i][j]\) i个字符走到节点j的概率,建出转移矩 ...
- CodeForces - 24D :Broken robot (DP+三对角矩阵高斯消元 随机)
pro:给定N*M的矩阵,以及初始玩家位置. 规定玩家每次会等概率的向左走,向右走,向下走,原地不动,问走到最后一行的期望.保留4位小数. sol:可以列出方程,高斯消元即可,发现是三角矩阵,O(N* ...
- UVA 11468 AC自动机入门题 记忆化概率dp+ac自动机
/** 链接:https://vjudge.net/problem/UVA-11468 详见lrj训练指南P218 我的是反向求存在模板串的概率. dp[i][j]表示当前i位置选择字符,前面i-1个 ...
- HDU 4089 Activation:概率dp + 迭代【手动消元】
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4089 题意: 有n个人在排队激活游戏,Tomato排在第m个. 每次队列中的第一个人去激活游戏,有可能 ...
- BZOJ4820 Sdoi2017 硬币游戏 【概率期望】【高斯消元】【KMP】*
BZOJ4820 Sdoi2017 硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实 ...
随机推荐
- C#反射调用小DEMO
程序集的源代码: namespace DesignMode { class IOCTest { public void TestO() { Console.WriteLine("O方法&qu ...
- spring (由Rod Johnson创建的一个开源框架)
你可能正在想“Spring不过是另外一个的framework”.当已经有许多开放源代码(和专有)J2EEframework时,我们为什么还需要Spring Framework? Spring是独特的, ...
- iOS面试题 第一天
今天上午,下午分别面试了两家公司.上午是一家互联网公司,气氛还比较好,是我比较喜欢的.技术这块是直接机试,主要是给了些BUG让我修复,整个过程还算顺利.下午去了一家大型的证券公司.整理技术问题如下: ...
- 【Python】使用cmd模块构造一个带有后台线程的交互命令行界面
最近写一些测试工具,实在懒得搞GUI,然后意识到python有一个自带模块叫cmd,用了用发现简直是救星. 1. 基本用法 cmd模块很容易学到,基本的用法比较简单,继承模块下的Cmd类,添加需要的功 ...
- 浏览器window产生的缓存九种解决办法
浏览器缓存(Browser Caching)是浏览器端保存数据用于快速读取或避免重复资源请求的优化机制,有效的缓存使用可以避免重复的网络请求和浏览器快速地读取本地数据,整体上加速网页展示给用户.浏览器 ...
- servlet多文件上传(带进度条)
需要commons-fileupload-1.3.jar和commons-io-2.4.jar的支持 页面效果:(图片文件都可以) (1)进度标识类 public class UploadStatus ...
- 响应式Web设计- 图片
使用width属性:如果width属性设置为100%,图片会根据上下范围实现响应式的功能. <!DOCTYPE html><html><head><meta ...
- SVN中检出(check out) 跟导出(export) 的区别
SVN中检出(check out) 和导出(export) 的区别?观点一:SVN是常用的一种常见的版本控制软件.SVN中检出(check SVN中检出(check out) 和导出(export ...
- CSS规范(OOCSS SMACSS BEM)
Css规范 OOCSS SMACSS BEM OOCSS(Object Oriented CSS)面向对象的css 主要分成四个部分 Template :模板 Grids :栅格布局 Module : ...
- 下载PhantomJS
PhantomJS新手?阅读并学习快速入门指南. 视窗 下载phantomjs-2.1.1-windows.zip(17.4 MB)并解压缩(解压缩)内容. 可执行文件phantomjs.exe已准备 ...