题意:

有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自动机,高斯消元)的更多相关文章

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

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

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

  3. BZOJ3270: 博物馆【概率DP】【高斯消元】

    Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博物馆.这座博物馆有着特别的样式.它包含由m条走廊连接的n间房间,并且满足可以从任何一 ...

  4. BZOJ3141 Hnoi2013 游走 【概率DP】【高斯消元】*

    BZOJ3141 Hnoi2013 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点 ...

  5. UVALive - 3490 Generator (AC自动机+高斯消元dp)

    初始有一个空串s,从前n个大写字母中不断随机取出一个字母添加到s的结尾,出现模式串t时停止,求停止时s的长度期望. 这道题解法不唯一,比较无脑的方法是对模式串t建一个单串AC自动机,设u为自动机上的一 ...

  6. BZOJ 1444: [Jsoi2009]有趣的游戏 [AC自动机 高斯消元]

    1444: [Jsoi2009]有趣的游戏 题意:每种字母出现概率\(p_i\),有一些长度len的字符串,求他们出现的概率 套路DP的话,\(f[i][j]\) i个字符走到节点j的概率,建出转移矩 ...

  7. CodeForces - 24D :Broken robot (DP+三对角矩阵高斯消元 随机)

    pro:给定N*M的矩阵,以及初始玩家位置. 规定玩家每次会等概率的向左走,向右走,向下走,原地不动,问走到最后一行的期望.保留4位小数. sol:可以列出方程,高斯消元即可,发现是三角矩阵,O(N* ...

  8. UVA 11468 AC自动机入门题 记忆化概率dp+ac自动机

    /** 链接:https://vjudge.net/problem/UVA-11468 详见lrj训练指南P218 我的是反向求存在模板串的概率. dp[i][j]表示当前i位置选择字符,前面i-1个 ...

  9. HDU 4089 Activation:概率dp + 迭代【手动消元】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4089 题意: 有n个人在排队激活游戏,Tomato排在第m个. 每次队列中的第一个人去激活游戏,有可能 ...

  10. BZOJ4820 Sdoi2017 硬币游戏 【概率期望】【高斯消元】【KMP】*

    BZOJ4820 Sdoi2017 硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实 ...

随机推荐

  1. O2O的十八个细分市场,运营模式如何?

    社区O2O,这个行业也被媒体热炒有三年多时间了,有没有做的还算不错的案例呢?万科.龙湖.恒大.保利.易居中国.彩生活.拉卡拉.顺丰?哪个可以称得上是成功案例?战略变来变去,方向换来换去,基本上都是雷声 ...

  2. 在tomcat中配置连接池

    在tomcat的conf/Catalina/localhost目录下配置项目路径,tomcat启动是会直接根据配置去加载项目. 虽然配置就一句话,但经常忘,今天记下来. 如果你的项目成名是:mypro ...

  3. html中注释的问题

    在修改jsp页面的时候遇到了一个有点难懂的注释,mark一下 <script> <!-- alert("js code"); //--> </scri ...

  4. 【Java_基础】java类加载过程与双亲委派机制

    1.类的加载.连接和初始化 当程序使用某个类时,如果该类还未被加载到内存中,则系统会通过加载.连接.初始化三个步骤来对类进行初始化.如果没有意外,jvm将会连续完成这三个步骤,有时也把这三个步骤统称为 ...

  5. 在已编译安装nginx上动态添加模块

    一.添加nginx模块 找到安装nginx的源码根目录,如果没有的话下载新的源码 wget http://nginx.org/download/nginx-1.8.1.tar.gz 查看ngixn版本 ...

  6. 【chm】【windows】win7下chm打开不显示内容

    修改chm属性里面,‘解除锁定’即可.点击chm文件,右键选择属性,点击最下方的解除锁定,保存,退出重新打开即可. ​

  7. Web框架之Django_10 重要组件(Auth模块)

    一.auth模块介绍 Auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等 ...

  8. python-格式化输出(考试必考)

    Python与用户交互 如何交互 我们使用input()方法来与用户交互,但是无论我们输入的值是数字类型.字符串类型.列表类型,input的接收值都是字符串类型. name = input('请输入你 ...

  9. 基础训练 Huffuman树

    Huffuman树 /*解法一*/ #include<iostream> #include<queue> using namespace std; int main(){ pr ...

  10. Luogu 2569 [SCOI2010]股票交易 (朴素动规转移 + 单调队列优化)

    题意: 已知未来 N 天的股票走势,第 i 天最多买进 as [ i ] 股每股 ap [ i ] 元,最多卖出 bs [ i ] 股每股 bp [ i ] 元,且每天最多拥有 Mp 股,且每两次交易 ...