[Sdoi2017]硬币游戏

题意:硬币序列,H T等概率出现,\(n \le 300\)个人猜了一个长为$ m \le 300$的字符串,出现即获胜游戏结束。求每个人获胜概率


考场用了[1444: Jsoi200]有趣的游戏的做法,40分

标解好神!

思想就是用N表示所有没有人获胜的状态,然后列方程

对于A,B两个串

例如:

A=TTH, B=HTT

那么N+TTH一定会到终止点,但不一定TTH加完后才停止

NTTH = A + BH + BTH

0.125N = A + 0.75B

获胜概率和为1

n+1个变量 n+1个方程 高斯消元

怎么解释呢?

就是把一些状态的概率用一些变量表示出来了呀

计算系数可以两两用kmp,求B再方程A中的系数:AB连起来求fail,然后得到后缀=前缀了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=305;
const double eps=1e-10;
inline int read() {
char c=getchar(); int x=0, f=1;
while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*f;
} int n, m;
char s[N][N];
double a[N][N], two[N];
namespace kmp {
char s[N<<1];
int fail[N];
void build(char *s, int n) {
fail[1] = 0;
for(int i=2; i<=n; i++) {
int now = fail[i-1];
while(now && s[i] != s[now+1]) now = fail[now];
fail[i] = s[i]==s[now+1] ? now+1 : 0;
}
}
double cal(char *a, char *b) {
int n = m<<1;
for(int i=1; i<=m; i++) s[i] = a[i];
for(int i=1; i<=m; i++) s[i+m] = b[i];
build(s, n);
//for(int i=1; i<=n; i++) printf("%d ", fail[i]); puts("");
int now = fail[n]; double ans = 0;
while(now) ans += two[m-now], now = fail[now];
//printf("ans %lf\n", ans);
return ans;
}
} void build() {
two[0]=1;
for(int i=1; i<=m; i++) two[i] = two[i-1] * 0.5; for(int i=1; i<=n; i++) a[n+1][i] = 1;
a[n+1][n+2] = 1;
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) a[i][j] = kmp::cal(s[i], s[j]);
a[i][n+1] = -two[m];
}
} void gauss(int n) {
//for(int i=1; i<=n; i++) for(int j=1; j<=n+1; j++) printf("%lf%c", a[i][j], j==n+1 ? '\n' : ' ');
for(int i=1; i<=n; i++) {
int r=i;
for(int k=i; k<=n; k++) if(abs(a[k][i]) > abs(a[r][i])) r=k;
if(r != i) for(int j=i; j<=n+1; j++) swap(a[r][j], a[i][j]); for(int k=i+1; k<=n; k++) {
double t = a[k][i] / a[i][i];
for(int j=i; j<=n+1; j++) a[k][j] -= t * a[i][j];
}
}
for(int i=n; i>=1; i--) {
for(int j=n; j>i; j--) a[i][n+1] -= a[i][j] * a[j][n+1];
a[i][n+1] /= a[i][i];
}
}
int main() {
freopen("game.in", "r", stdin);
freopen("game.out", "w", stdout);
n=read(); m=read();
for(int i=1; i<=n; i++) scanf("%s", s[i]+1);
build();
gauss(n+1);
for(int i=1; i<=n; i++) printf("%.10lf\n", a[i][n+2]);
}

[Sdoi2017]硬币游戏 [高斯消元 KMP]的更多相关文章

  1. [BZOJ4820][SDOI2017]硬币游戏(高斯消元+KMP)

    比较神的一道题,正解比较难以理解. 首先不难得出一个(nm)^3的算法,对所有串建AC自动机,将在每个点停止的概率作为未知数做高斯消元即可. 可以证明,AC自动机上所有不是模式串终止节点的点可以看成一 ...

  2. [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)

    [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...

  3. BZOJ4820 SDOI2017硬币游戏(概率期望+高斯消元+kmp)

    容易想到的做法是建出AC自动机,高斯消元.然而自动机上节点数量是nm的. 注意到我们要求的变量只有n个,考虑将其他不用求的节点合并为一个变量.这个变量即表示随机生成一个串,其不包含任何一个模板串的概率 ...

  4. 【bzoj3105】[cqoi2013]新Nim游戏 高斯消元求线性基

    题目描述 传统的Nim游戏是这样的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴数量可以不同).两个游戏者轮流操作,每次可以选一个火柴堆拿走若干根火柴.可以只拿一根,也可以拿走整堆火柴,但不能同时从 ...

  5. BZOJ 3105: [cqoi2013]新Nim游戏 [高斯消元XOR 线性基]

    以后我也要用传送门! 题意:一些数,选择一个权值最大的异或和不为0的集合 终于有点明白线性基是什么了...等会再整理 求一个权值最大的线性无关子集 线性无关子集满足拟阵的性质,贪心选择权值最大的,用高 ...

  6. UVA 1358 - Generator(dp+高斯消元+KMP)

    UVA 1358 - Generator option=com_onlinejudge&Itemid=8&page=show_problem&category=524& ...

  7. BZOJ 2466 中山市选2009 树 高斯消元+暴力

    题目大意:树上拉灯游戏 高斯消元解异或方程组,对于全部的自由元暴力2^n枚举状态,代入计算 这做法真是一点也不优雅... #include <cstdio> #include <cs ...

  8. BZOJ.4820.[SDOI2017]硬币游戏(思路 高斯消元 哈希/AC自动机/KMP)

    BZOJ 洛谷 建出AC自动机,每个点向两个儿子连边,可以得到一张有向图.参照 [SDOI2012]走迷宫 可以得到一个\(Tarjan\)+高斯消元的\(O((nm)^3)\)的做法.(理论有\(6 ...

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

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

随机推荐

  1. poj1258prim算法

    /*poj 1258 *题意:有若干个农场,现需要将各个农场用光纤连接起来,各个农场之间连接的光纤长度也许不同, *要求求出使得将所有农场连接起来的最短光线长度 *算法分析:使用矩阵将各个农场之间的光 ...

  2. Java集合系列[4]----LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHas ...

  3. Linux中安装opencv-3.3.1

    在ubuntu16.04中安装opencv3.3.1的过程中踩了许多坑.一开始直接安装还挺顺利但运行程序时总是提示libgtk2.0-dev和pkg-config没有安装,在安装这两个包的过程中也不顺 ...

  4. DEDECMS中的几个常见的自定义常量DEDEMEMBER等位置

    http://www.dede58.com/a/dedejq/3567.html dedecms新建栏目时默认都是允许投稿的,可以投稿本来对网站来说是件好事,但是dedecms是开源的,使用太广泛了, ...

  5. JAVA WEB之Spring4.x JdbcTemplate

    jdbcTemplate 说白了,他就是Spring提供用于简化数据库访问的类 基本jdbc驱动访问数据库 /* 一个简易好用的数据库连接和访问类 */ package cslg.cn.control ...

  6. Dos下的小技巧

    1.dos 窗口下怎样复制粘贴 第一种方式:右键标记-->选中-->标题栏右键编辑-->复制 第二种方式:右键-->标记-->选中-->enter 这样就可以复制了 ...

  7. Python3基础知识之元组、集合、字典

    1.元组 元组特点元组是不可变的两个元组可以做加法,不能做减法 元组的方法 >>> S('a', 'b', 'c', 'd', 'e')>>> S=('a','b' ...

  8. P1144 最短路计数

    P1144 最短路计数 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶 ...

  9. javascript属性之get/set

    var o = { get x(){ return 7; }, set x(val){ console.info("不能设置x的值"); } } o.x //7 读取x值的时候,会 ...

  10. python2.7.5 安装pip 良心推荐,超级简单.

    1 先安装setuptools 下载地址:https://pypi.python.org/pypi/setuptools#downloads 将下载后的tar文件解压,用CMD模式进入到解压后的文件所 ...