考虑生成函数来做

g(x)函数就是0+0*x+...+1*x^s+...+|∑|^(n-s)x^n

就是最后s位必须填这个串,但是前面随便填的方案数

然后枚举之前出现了哪个串(包括自己),如果没有相交,就是fj(x)*g(x),还有就是有前后缀有相交部分,

Pji(x)中的第k位,表示i的长度为m-k的前缀和j的长度为m-k的后缀是不是一样 0/1。

再加上最后一个

$\sum f_i=1$因为游戏最终会停止

现在有n+1个方程,g(x)直接当做未知数的话会有交叉项解不出来

把$(1-|\Sigma|x)$乘过去,求导来搞搞事情:

由于带入$x=1/|\Sigma|$使得这个$(1-|\Sigma|x)$等于0,求导可以消去一些项

$-|\Sigma|fi=S(x)^{S-1}-Sx^{S-1}(\sum_jf_j)-x^S(\sum_jf'_j)+|\Sigma|(\sum_jf_jP_{ji})$

把$(\sum_jf'_j)$当做另外一个未知量

就有n+1个未知量,n+1个方程了

根据“洛必达法则”(一种极限处理)由于最后是收敛的,一定有极限,所以带入​当x=1/|∑|的时候不会除以0成为很大的数(我在口胡)

代码:
卡精度,不用eps反而更好

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define ld long double
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=303;
const double eps=1e-8;
const ll mod[2]={1000000007,998244353};
const ll jin[2]={131,13331};
ll pw[N][2];
ll has[N][N][2];
char s[N];
ld f[N][N];
ld ans[N];
int n,m;
ld m0,m1;
bool cmp(ld x){return 1;
}
void Guass(int n){for(reg i=1;i<=n;++i){int id=0;for(reg j=i;j<=n;++j){if(cmp(f[j][i])&&fabs(f[j][i])>fabs(f[id][i])) id=j;}if(id!=i){for(reg j=1;j<=n+1;++j){swap(f[i][j],f[id][j]);}}for(reg j=i+1;j<=n;++j){if(cmp(f[j][i])){ld tmp=f[j][i]/f[i][i];for(reg k=1;k<=n+1;++k){f[j][k]=f[j][k]-f[i][k]*tmp;}}}}for(reg i=n;i>=1;--i){for(reg j=1;j<=n;++j){if(cmp(ans[j])) f[i][n+1]-=ans[j]*f[i][j];}ans[i]=f[i][n+1]/f[i][i];}
}
int main(){rd(n);rd(m);pw[0][0]=pw[0][1]=1;for(reg i=1;i<=m;++i){for(reg j=0;j<=1;++j){pw[i][j]=pw[i-1][j]*jin[j]%mod[j];}}for(reg i=1;i<=n;++i){scanf("%s",s+1);for(reg j=1;j<=m;++j){for(reg l=0;l<=1;++l){has[i][j][l]=(has[i][j-1][l]*jin[l]+s[j]-'A')%mod[l];}}}m0=m1=1.0;for(reg i=1;i<=m;++i) m1=m1*0.5;m0=m1*2;for(reg i=1;i<=n;++i){//    cout<<" turns "<<i<<" ----------------------- "<<endl;for(reg j=1;j<=n;++j){//    cout<<" with "<<j<<endl;ld tmp=0.5;ld val=0;for(reg k=1;k<=m-1;++k){int to=m-k;ll bac0=(has[j][m][0]-has[j][m-to][0]*pw[to][0]%mod[0]+mod[0])%mod[0];ll bac1=(has[j][m][1]-has[j][m-to][1]*pw[to][1]%mod[1]+mod[1])%mod[1];if(bac0==has[i][to][0]&&bac1==has[i][to][1]){//    cout<<" ok "<<to<<endl;val+=tmp;}tmp*=0.5;}//    cout<<" val "<<val<<endl;f[i][j]=m*m0-2.0*val;}f[i][i]-=2.0;f[i][n+1]=m1;f[i][n+2]=m*m0;}for(reg i=1;i<=n;++i){f[n+1][i]=1.0;}f[n+1][n+2]=1.0;//    for(reg i=1;i<=n+1;++i){
//        for(reg j=1;j<=n+2;++j){
//            cout<<f[i][j]<<" ";
//        }cout<<endl;
//    }Guass(n+1);for(reg i=1;i<=n;++i){printf("%.10Lf\n",ans[i]);}return 0;
}}
signed main(){Miracle::main();return 0;
}/*Author: *Miracle*Date: 2019/2/18 17:41:21
*/

总结:

对于连续一些位置有值的时候,
生成函数确实很好用

求导由于可以降次,这里就把交叉项成功分开了。

PS:这个题也有直接上概率的做法,本质和生成函数相同。但是解释起来最好的绝对是生成函数

转载于:https://www.cnblogs.com/Miracevin/p/10397957.html

[SDOI2017]硬币游戏相关推荐

  1. [Sdoi2017]硬币游戏 [高斯消元 KMP]

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

  2. 【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)

    [BZOJ4820][SDOI2017]硬币游戏(高斯消元) 题面 BZOJ 洛谷 题解 第一眼的感觉就是构\(AC\)自动机之后直接高斯消元算概率,这样子似乎就是\(BZOJ1444\)了.然而点数 ...

  3. P3706 [SDOI2017]硬币游戏

    P3706 [SDOI2017]硬币游戏 题目描述 Solution 前置技能: P4548 [CTSC2006]歌唱王国 歌唱王国就是n=1n=1n=1的情况. 我们用类似的方法,先考虑两个串的情况 ...

  4. BZOJ:4820: [Sdoi2017]硬币游戏BZOJ:1444: [Jsoi2009]有趣的游戏(高斯消元求概率)

    1444: [Jsoi2009]有趣的游戏 4820: [Sdoi2017]硬币游戏 这两道题都是关于不断随机生成字符后求出现给定字符串的概率的问题. 第一题数据范围较小,将串建成AC自动机以后,以A ...

  5. BZOJ4820 [SDOI2017]硬币游戏

    BZOJ4820 [SDOI2017]硬币游戏 题面:BZOJ 解析 考虑把所有没有到达结束状态的字符串看做一类字符串\(N\),把以字符串\(i\)作为结束的一类字符串\(i\).现在假设猜测了两个 ...

  6. bzoj 4820: [Sdoi2017]硬币游戏 概率dp+高斯消元+KMP

    题意 周末同学们非常无聊,有人提议,咱们扔硬币玩吧,谁扔的硬币正面次数多谁胜利. 大家纷纷觉得这个游戏非常符合同学们的特色,但只是扔硬币实在是太单调了. 同学们觉得要加强趣味性,所以要找一个同学扔很多 ...

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

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

  8. bzoj4820 [Sdoi2017]硬币游戏 高斯消元+概率+kmp

    有环的概率是可以高斯消元的 由于匹配情况可能从一个串转移到另一个串,所以需要建一个转移关系的图 就可以建一个ac自动机,但节点数是nm的.就可以设未知数,然后凑一些方程. 设N表示没有任何人获胜的概率 ...

  9. codevs 5966 [SDOI2017]硬币游戏

    输入描述 Input Description 输入输出数据精度为1e-10 [题解] #include<cstdio> using namespace std; const int N=1 ...

最新文章

  1. Linux实现ffmpeg H.265视频编码
  2. sdr 软件_SDR 软件定义的无线电
  3. 从未在一起更让人遗憾_我们从未在一起和我们最终没在一起,哪一个更让人难过?...
  4. 易语言tcp多线程服务端客户端_从TCP协议到TCP通信的各种异常现象和分析
  5. [HDU 1254] 推箱子
  6. java生产者消费者问题代码分析
  7. iic总线从机仲裁_I2C总线的仲裁问题
  8. 信息学奥赛C++语言:三个数的大小比较
  9. Linux之网络管理(6)ip及路由相关命令
  10. Sublime Text 3 注册码失效(被移除)解决方法
  11. 头衔的权威暗示影响力
  12. 干货:完全基于情感词典的文本情感分析
  13. 可用等式为:html+java=jsp表示jsp[8]._在 JSP 中 , 对 jsp:setProperty 标记描述正确的是 ()_学小易找答案...
  14. 图像处理--最大内接圆
  15. Python自动抢红包,从此再也不会错过微信红包了!
  16. 打开php文件url格式,url格式是什么
  17. 【转贴】龙芯生态产品和解决方案巡展(第四篇)——存储
  18. 【已解决】MAC OS上teamviewer商业用途中断连接
  19. np.arange函数
  20. 流量从“海量”到“僵化”,精细化运营是企业最后一根救命稻草

热门文章

  1. [BZOJ 3211]花神游历各国(并查集+树状数组)
  2. SQL SERVER出现大量一致性错误的解决方法
  3. Zend Studio 12 windows 无限期试用
  4. LeetCode算法题-Nth Digit(Java实现)
  5. java笔记 -- 输入输出
  6. cocos studio和cocos creator关系
  7. 全球投资者为阿里尖叫!阿里CEO张勇详解天猫商业新力量
  8. 每个设计师需知的40个设计素材站
  9. C#资源释放及Dispose、Close和析构方法
  10. 基于BitBox的Wormhole SDK 已迭代至1.0.0版本