【BZOJ4820】[Sdoi2017]硬币游戏

Description

周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利。大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了。同学们觉得要加强趣味性,所以要找一个同学扔很多很多次硬币,其他同学记录下正反面情况。用H表示正面朝上,用T表示反面朝上,扔很多次硬币后,会得到一个硬币序列。比如HTT表示第一次正面朝上,后两次反面朝上。但扔到什么时候停止呢?大家提议,选出n个同学,每个同学猜一个长度为m的序列,当某一个同学猜的序列在硬币序列中出现时,就不再扔硬币了,并且这个同学胜利,为了保证只有一个同学胜利,同学们猜的n个序列两两不同。很快,n个同学猜好序列,然后进入了紧张而又刺激的扔硬币环节。你想知道,如果硬币正反面朝上的概率相同,每个同学胜利的概率是多少。

Input

第一行两个整数n,m。
接下里n行,每行一个长度为m的字符串,表示第i个同学猜的序列。
1<=n,m<=300

Output

输出n行,第i行表示第i个同学胜利的概率。
输出与标准输出的绝对误差不超过10^-6即视为正确。

Sample Input

3 3
THT
TTH
HTT

Sample Output

0.3333333333
0.2500000000
0.4166666667

题解:网上看了好多题解都很难懂,我换一种理解方式来说吧~

我们设与所有字符串都不匹配的串的期望长度为N,同时,期望长度也可以表示每个串的期望经过次数,因为所有串的期望经过次数之和为1,那么它也可以用来表示每个人获胜的概率。具体的说,每一个跟所有串都不匹配的串出现的概率都是相同的,它们的和就是N。(这几句话是做这道题的先决条件。)

枚举每个字符串,设当前枚举到A,我们在N后面强行加上一个串A,形成NA,它出现的概率自然就是${N\over 2^m}$,那么它是不是就是A获胜的概率呢?显然不是。因为N的后缀是不确定的,在强行加上串A时,它有可能提前形成了别的串(或者提前形成了串A本身),那么NA的概率自然就是这些情况发生的概率之和。具体地,如果:A的x前缀是B的x后缀,那么N的m-x后缀就是B的前缀,它发生的概率为$1\over 2^{m-x}$,所以当我们在AC自动机上找出所有这样的B和x后,就能得到:

$P_{NA}={P_N\over 2^m}=\sum{P_B\over 2^{m-x}}+P_A$

此外,我们还有方程$\sum Pi=1$,所以就有n+1个未知数和n+1个方程,高斯消元就好了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
typedef long double ld;
const ld eps=1e-10;
int n,m,tot;
int pos[310],dep[90010];
struct acm
{
int ch[2],fail,dan;
}p[90010];
char str[310][310];
ld v[310][310],m2[310];
queue<int> q;
void build()
{
int i,u;
q.push(1);
while(!q.empty())
{
u=q.front(),q.pop();
for(i=0;i<=1;i++)
{
if(!p[u].ch[i])
{
if(u==1) p[u].ch[i]=1;
else p[u].ch[i]=p[p[u].fail].ch[i];
continue;
}
q.push(p[u].ch[i]);
if(u==1) p[p[u].ch[i]].fail=1;
else p[p[u].ch[i]].fail=p[p[u].fail].ch[i];
}
}
}
void gauss()
{
int i,j,k; ld t;
n++;
for(i=1;i<=n;i++)
{
for(j=i;j<=n;j++) if(fabs(v[j][i])>fabs(v[i][i])) for(k=1;k<=n+1;k++) swap(v[i][k],v[j][k]);
t=v[i][i];
for(k=i;k<=n+1;k++) v[i][k]/=t;
for(j=1;j<=n;j++) if(i!=j)
{
t=v[j][i];
for(k=1;k<=n+1;k++) v[j][k]-=t*v[i][k];
}
}
n--;
}
int main()
{
scanf("%d%d",&n,&m);
int i,j,u,a,t;
for(m2[0]=1.0,i=1;i<=m;i++) m2[i]=m2[i-1]*0.5;
for(tot=i=1;i<=n;i++)
{
scanf("%s",str[i]);
for(u=1,j=0;j<m;j++)
{
a=(str[i][j]=='T');
if(!p[u].ch[a]) p[u].ch[a]=++tot;
u=p[u].ch[a];
}
p[u].dan=i,pos[i]=u;
}
build();
for(i=1;i<=n;i++)
{
for(u=1,j=0;j<m;j++) u=p[u].ch[str[i][j]=='T'],dep[u]=j+1;
v[i][n+1]=m2[m];
for(j=1;j<=n;j++) for(t=pos[j];t;t=p[t].fail) if(dep[t]) v[i][j]+=m2[m-dep[t]];
for(u=1,j=0;j<m;j++) u=p[u].ch[str[i][j]=='T'],dep[u]=0;
}
for(i=1;i<=n;i++) v[n+1][i]=1;
v[n+1][n+2]=1;
gauss();
for(i=1;i<=n;i++) printf("%.10lf\n",(double)v[i][n+2]);
return 0;
}

【BZOJ4820】[Sdoi2017]硬币游戏 AC自动机+概率DP+高斯消元的更多相关文章

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

  2. 4.23 子串 AC自动机 概率期望 高斯消元

    考虑40分. 设出状态 f[i]表示匹配到了i位还有多少期望长度能停止.可以发现这个状态有环 需要高斯消元. 提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+ ...

  3. BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元

    BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元 题意: 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 3 ...

  4. LightOJ - 1151概率dp+高斯消元

    概率dp+高斯消元 https://vjudge.net/problem/LightOJ-1151 题意:刚开始在1,要走到100,每次走的距离1-6,超过100重来,有一些点可能有传送点,可以传送到 ...

  5. 【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元

    题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两 ...

  6. BZOJ3270 博物館 概率DP 高斯消元

    BZOJ3270 博物館 概率DP 高斯消元 @(XSY)[概率DP, 高斯消元] Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博 ...

  7. BZOJ 3270: 博物馆 [概率DP 高斯消元]

    http://www.lydsy.com/JudgeOnline/problem.php?id=3270 题意:一张无向图,一开始两人分别在$x$和$y$,每一分钟在点$i$不走的概率为$p[i]$, ...

  8. 【BZOJ3640】JC的小苹果 概率DP+高斯消元

    [BZOJ3640]JC的小苹果 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话说JC历经艰辛来到了城市B,但 ...

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

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

随机推荐

  1. mongodb修改器(转)

    MongoDB 修改器 对文档中的某些字段进行更新 $inc 专门用来增加(或减少)数字的,只能用于整数,长整数或双精度浮点型的值$inc键的值必须为数字,不能使用字符串,数组或其他非数字的值如果键不 ...

  2. jdk/java版本与Android源码编译中的错误

    错误一:javap未指向有效的java版本 Traceback (most recent call last): File "../../base/android/jni_generator ...

  3. How to Configure an SSIS Package to Access a Web Service using WCF

    This information is from:http://blogs.msdn.com/b/dbrowne/archive/2010/07/08/how-to-configure-an-ssis ...

  4. Django——快速实现注册

    前言 对于web开来说,用户登陆.注册.文件上传等是最基础的功能,针对不同的web框架,相关的文章非常多,但搜索之后发现大多都不具有完整性,对于想学习web开发的新手来说不具有很强的操作性:对于web ...

  5. vue 生命周期组件渲染

    1.created 实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调.然而,挂载阶段还没开始,$el 属性目前不可见. 2.mount ...

  6. 《Android源代码设计模式解析与实战》读书笔记

    1.定义 将对象组合成树形结构以表示"部分-总体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 2.使用场景 (1)表示对象的部分-总体层次结构时. (2)从一个总体 ...

  7. 【BIEE】07_调整BIEE柱子的显示顺序

    现在有报表如下: 但是我们觉得这种显示不好看,想把非优秀员工的柱子放在前边显示,那么如何调整呢? 调整步骤: [编辑分析] 我们将此处条形图下的两个标签顺序重新调整一下 从上图可以看出,效果明显!

  8. Android蓝牙

    代码地址如下:http://www.demodashi.com/demo/12772.html 前言:最近,新换了一家公司,公司的软件需要通过蓝牙与硬件进行通讯,于是趁此机会将Android蓝牙详细的 ...

  9. java检测http请求的ip地址 Java问题通用解决代码

    以后再用到的话,至少能起个参考作用 java实现,struts2的Action中,依赖HttpServletRequest     package net.dookoo.web.action;   i ...

  10. 前端性能优化--为什么DOM操作慢? 浅谈DOM的操作以及性能优化问题-重绘重排 为什么要减少DOM操作 为什么要减少操作DOM

    前端性能优化--为什么DOM操作慢?   作为一个前端,不能不考虑性能问题.对于大多数前端来说,性能优化的方法可能包括以下这些: 减少HTTP请求(合并css.js,雪碧图/base64图片) 压缩( ...