【BZOJ4820】[Sdoi2017]硬币游戏 AC自动机+概率DP+高斯消元
【BZOJ4820】[Sdoi2017]硬币游戏
Description
Input
Output
Sample Input
THT
TTH
HTT
Sample Output
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+高斯消元的更多相关文章
- 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 ...
- 4.23 子串 AC自动机 概率期望 高斯消元
考虑40分. 设出状态 f[i]表示匹配到了i位还有多少期望长度能停止.可以发现这个状态有环 需要高斯消元. 提供一种比较简单的方法:由于期望的线性可加性 可以设状态f[i]表示由匹配到i到匹配到i+ ...
- BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元
BZOJ_1778_[Usaco2010 Hol]Dotp 驱逐猪猡_概率DP+高斯消元 题意: 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 3 ...
- LightOJ - 1151概率dp+高斯消元
概率dp+高斯消元 https://vjudge.net/problem/LightOJ-1151 题意:刚开始在1,要走到100,每次走的距离1-6,超过100重来,有一些点可能有传送点,可以传送到 ...
- 【bzoj1778】[Usaco2010 Hol]Dotp 驱逐猪猡 矩阵乘法+概率dp+高斯消元
题目描述 奶牛们建立了一个随机化的臭气炸弹来驱逐猪猡.猪猡的文明包含1到N (2 <= N <= 300)一共N个猪城.这些城市由M (1 <= M <= 44,850)条由两 ...
- BZOJ3270 博物館 概率DP 高斯消元
BZOJ3270 博物館 概率DP 高斯消元 @(XSY)[概率DP, 高斯消元] Description 有一天Petya和他的朋友Vasya在进行他们众多旅行中的一次旅行,他们决定去参观一座城堡博 ...
- BZOJ 3270: 博物馆 [概率DP 高斯消元]
http://www.lydsy.com/JudgeOnline/problem.php?id=3270 题意:一张无向图,一开始两人分别在$x$和$y$,每一分钟在点$i$不走的概率为$p[i]$, ...
- 【BZOJ3640】JC的小苹果 概率DP+高斯消元
[BZOJ3640]JC的小苹果 Description 让我们继续JC和DZY的故事. “你是我的小丫小苹果,怎么爱你都不嫌多!” “点亮我生命的火,火火火火火!” 话说JC历经艰辛来到了城市B,但 ...
- hdu5955 Guessing the Dice Roll【AC自动机】【高斯消元】【概率】
含高斯消元模板 2016沈阳区域赛http://acm.hdu.edu.cn/showproblem.php?pid=5955 Guessing the Dice Roll Time Limit: 2 ...
随机推荐
- 信号驱动IO
[1]信号驱动IO 应用程序:1)应用程序要捕捉SIGIO信号 signal(SIGIO, handler); 2)应用程序要指定进程为文件的属主,设置当前的文件描述为当前的调用进 ...
- jstl <fmt:formatDate>标签
<fmt:formatDate>标记用于在各种不同的方式来格式化日期 属性: <fmt:formatDate>标签具有以下属性: 属性 描述 必需 默认值 value 要显示的 ...
- consist of, made up of
consist vi.由……组成:由……构成(常和介词of构成固定搭配)made up of由……组成[例如] One year consists of 365 days.一年有365天.The te ...
- JSP Response Set Status
JSP Response Set Status In this tutorial you will learn about how to set the HTTP status code in JSP ...
- ECSHOP站内页面跳转,避免死链
2.x版本域名重定向: # For ISAPI_Rewrite 2.x RewriteCond Host: ^steveluo\.name$ RewriteRule (.*) http\://www\ ...
- Microsoft .Net Remoting
什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式.从微软的产品角度来看,可以说Remoting就是DCOM的一种升级,它改善了很多功能,并极好的融合到.Net平台下.Micros ...
- 三分钟教你学Git(十三) - 二分查找
比方说你收到了错误报告,然后你知道前几天明明是好的.可是这几天有好多新的commit被部署了.那么我们怎么迅速的找到第一个引入Bug的commit呢? 我们能够使用git bisect,git利用二分 ...
- 使用ByteRef加速String类型DocValues的载入
眼下商户索引DocValues很大,warmup时花费70-80秒(在beta环境),有62秒在载入DocValues,发现当中有54秒时间在载入string docvalues,string doc ...
- chown将指定文件的拥有者改为指定的用户或组(转)
chown将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户ID:组可以是组名或者组ID:文件是以空格分开的要改变权限的文件列表,支持通配符.系统管理员经常使用chown命令,在将文件拷贝 ...
- linux ln 命令使用参数详解(ln -s 软链接)(转)
这是linux中一个非常重要命令,请大家一定要熟悉.它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,具体用法是:ln -s 源文件 目标文件. 当 我们需要在不同的 ...