luogu3706 [SDOI2017]硬币游戏
LINK:硬币游戏
对于40分的暴力 构造出AC自动机 列出转移矩阵 暴力高消。右转上一篇文章。
对于100分 我们不难想到这个矩阵过大 且没有用的节点很多我们最后只要n个节点的答案 其他节点的答案可以不要。
考虑把没用的节点的答案压到一点上。相同的套路 我们设f[i]表示经过第i个点的期望次数 由于是到达某个点我们强制停止 所以概率*结果=期望次数。
此时结果为1/0 所以这个期望次数在数值之上和概率是相等的。
对于第i个终止节点来说我们考虑一下这个点的期望次数怎么求出。
显然是由非终止节点转移过来 由于每次翻硬币只有两种可能 或者说字符集大小为2 所以转移过来至少需要m条边且 概率为\(\frac{1}{2^m}\)
但是这其中存在一些不合法的情况 如 我们从一个非法状态转移+自身前缀状态的一部分 可能恰好和其他字符串是相等的 此时游戏结束概率也转移不来。
要把这些情况造成的影响全部减掉 \(f_i=\frac{1}{2^m}f_0-...\)上面的事情发生在当前字符串的前缀和其他字符串的后缀相等时会发生。
考虑匹配的长度为k 那个点为j 那么我们要减去 \(\frac{1}{2^{m-k}}f_j\) 所代表的含义为 前m-k长度的那个点的期望次数为 f_j的期望次数的一部分
于是乎就可以列出n个方程 但是有n+1个未知数 考虑加一个方程 \(\sum{f_i}=1\)
写到这里我想就很明朗了 很不错的题目。
这里使用hash判断前后缀 注意初始化的问题 我们对于f[i]的单项系数也在判断前后缀中搞。这样比较方便不需要特判最后一位什么的。
而且最后一位也不合法不属于0号节点里面 所以可以这样做 我迷了半天。。
const int MAXN=310;
int n,m;
char b[MAXN][MAXN];
db a[MAXN][MAXN],p[MAXN];
ll pw[MAXN],qz[MAXN][MAXN],hz[MAXN][MAXN];
inline void GAUSS()
{
for(int i=0;i<=n;++i)
{
int p=i;
for(int j=i+1;j<=n;++j)if(fabs(a[j][i])>fabs(a[p][i]))p=j;
if(i!=p)rep(0,n+1,j)swap(a[i][j],a[p][j]);
rep(0,n,j)
{
if(i==j)continue;
db d=a[j][i]/a[i][i];
rep(0,n+1,k)a[j][k]-=a[i][k]*d;
}
}
rep(0,n,i)a[i][n+1]/=a[i][i];
}
int main()
{
freopen("1.in","r",stdin);
gt(n);gt(m);p[0]=pw[0]=1;
rep(1,n,i)scanf("%s",b[i]+1);
rep(1,m,i)p[i]=p[i-1]/2,pw[i]=pw[i-1]*P%mod;
rep(1,n,i)rep(1,m,j)
{
qz[i][j]=(qz[i][j-1]*P+b[i][j])%mod;
hz[i][j]=(hz[i][j-1]+b[i][m-j+1]*pw[j-1])%mod;
}
rep(1,n,i)
{
a[i][0]+=p[m];
rep(1,n,j)rep(1,m,k)
if(qz[i][k]==hz[j][k])a[i][j]=a[i][j]-p[m-k];
}
rep(1,n+1,i)a[0][i]=1;
//rep(0,n,i){rep(0,n+1,j)cout<<a[i][j]<<' ';cout<<endl;}
GAUSS();
rep(1,n,i)printf("%.10lf\n",a[i][n+1]);
return 0;
}
update:写完后2h又发现了点其他东西 想了半天 发现上述等式没有错。
等式阐述了一个类似于容斥的东西。其中 对于特定的某个点 我们想要走到\(2^{m-k}\)需要这个概率 而右边虽然是 \(2^m\)的系数 但是其代表了后来是走到了fj的
而我们的前者则是 固定为fj 所以这两个东西显然相等。
又思考了20min 想到了一个更合理的思路。还是关于式子的问题。
我们考虑 减掉不合法方案 设不合法方案的点 为w 我们其实多加了一个 \(f_w\frac{1}{2^m}\) 在左边减掉其。
首先我们要先走到w这个点 设此匹配长度为k 那么概率为\(\frac{1}{2^{m-k}}\) 其期望要再乘上fj。
感觉证明还是很不顺畅 先咕了。
luogu3706 [SDOI2017]硬币游戏的更多相关文章
- BZOJ:4820: [Sdoi2017]硬币游戏&&BZOJ:1444: [Jsoi2009]有趣的游戏(高斯消元求概率)
1444: [Jsoi2009]有趣的游戏 4820: [Sdoi2017]硬币游戏 这两道题都是关于不断随机生成字符后求出现给定字符串的概率的问题. 第一题数据范围较小,将串建成AC自动机以后,以A ...
- [Sdoi2017]硬币游戏 [高斯消元 KMP]
[Sdoi2017]硬币游戏 题意:硬币序列,H T等概率出现,\(n \le 300\)个人猜了一个长为$ m \le 300$的字符串,出现即获胜游戏结束.求每个人获胜概率 考场用了[1444: ...
- 【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)
[BZOJ4820][SDOI2017]硬币游戏(高斯消元) 题面 BZOJ 洛谷 题解 第一眼的感觉就是构\(AC\)自动机之后直接高斯消元算概率,这样子似乎就是\(BZOJ1444\)了.然而点数 ...
- 4820: [Sdoi2017]硬币游戏
4820: [Sdoi2017]硬币游戏 链接 分析: 期望dp+高斯消元. 首先可以建出AC自动机,Xi表示经过节点i的期望次数,然后高斯消元,这样点的个数太多,复杂度太大.但是AC自动机上末尾节点 ...
- BZOJ4820 Sdoi2017 硬币游戏 【概率期望】【高斯消元】【KMP】*
BZOJ4820 Sdoi2017 硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实 ...
- 【BZOJ4820】[Sdoi2017]硬币游戏 AC自动机+概率DP+高斯消元
[BZOJ4820][Sdoi2017]硬币游戏 Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬 ...
- [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)
[BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...
- [bzoj4820][Sdoi2017]硬币游戏
来自FallDream的博客,未经允许,请勿转载,谢谢. 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了 ...
- BZOJ 4820 [SDOI2017] 硬币游戏
Description 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利.大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了.同学们觉得要加强趣味性,所以要找 ...
随机推荐
- (二)ansible 使用
一,ansible 命令格式 #ansible <pattern> -m <module_name> -a <arguments> #单个服务器 ansible 3 ...
- ICPC 2018 亚洲横滨赛 C Emergency Evacuation(暴力,贪心)
ICPC 2018 亚洲横滨赛 C Emergency Evacuation 题目大意 你一个车厢和一些人,这些人都坐在座位上,求这些人全部出去的时间最小值 Solution 题目咋说就咋做 直接模拟 ...
- 洛谷 P4408 [NOI2003]逃学的小孩
题目传送门 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚, ...
- if与switch(break穿透)
## if与switch(分支语句) ### 一.if...else if...else1.语法 if(条件表达式1){ 语句体1; }else if(条件表达式2){ 语句体2; }else{ 语句 ...
- 【ASP.NET Core】mdl conflicts with tinymce
When I implementd the popular Richtext Editor tinymce for this web application, it conflicts with ma ...
- postman 进阶技巧
cookie 清除缓存 code 生成接口自动化测试脚本 响应部分 pretty 响应以json或xml显示 raw 响应以文本显示 preview 以HTML网页行驶显示 断言 断言:用于判断接口请 ...
- java 基本语法(七) 流程控制(四) 补充:Scanner类的使用
/* 如何从键盘获取不同类型的变量:需要使用Scanner类 具体实现步骤: 1.导包:import java.util.Scanner; 2.Scanner的实例化:Scanner scan = n ...
- 数据可视化之powerBI技巧(九)PowerBI按周进行业务分析的思路
按周进行数据分析,在零售业.电商等类型的公司中很常见,但是不少人觉得按周进行分析无从下手,一个主要的原因是找不到对应的函数,因为时间智能函数只对应年.季.月.天这几个粒度,没有关于周的时间智能函数. ...
- redis(十五):Redis 有序集合(sorted set)(python)
#coding:utf8 import redis r =redis.Redis(host="23.226.74.190",port=63279,password="66 ...
- nginx极简教程
Nginx 极简教程 本项目是一个 Nginx 极简教程,目的在于帮助新手快速入门 Nginx. examples 目录中的示例模拟了工作中的一些常用实战场景,并且都可以通过脚本一键式启动,让您可以快 ...