题目

太郎和一只免子正在玩一个掷骰子游戏。有一个有N个格子的长条棋盘,太郎和兔子轮流掷一个有M面的骰子,骰子M面分别是1到M的数字.且掷到任意一面的概率是相同的.掷到几.就往前走几步.当谁走到第N格时,谁就获胜了。游戏中还有一个规则“反弹”.就是当一位选手要走到第N格外时.他就会后退(就像飞行棋进营一样)。

假设现在一位追手在A格.当他掷出B时:

1.A+B<N,走到第A+B.络,

2.A+B=N,走到第N格,获胜。

3.A+B≥N,走到第(N-(A+B-N)格

现在太郎和兔子分别在第x和y格.接下来是太郎掷骰子,太郎想知道他赢得比赛的概率就多少。

分析

设\(f_{i,j}\)表示太郎在i,兔子在j,太郎的胜率。我们从后往前转移。

我们分四种情况:

1、i+m<=n and j+m<=n
2、i+m>n and j+m<=n
3、i+m<=n and j+m>n
4、i+m>n and j+m>n

why?

因为发现,当\(i+m>n\)时,i怎么跳总是\(i+m>n\),那么就可以把它们当做同一种状态。j也一样。

情况一:i+m<=n and j+m<=n

因为i走到k的概率为\(\dfrac{1}{m}\),j走到l的概率也为\(\dfrac{1}{m}\),

那么状态(i,j)的胜率就是状态(k,l)胜率的总和。

\[f_{i,j}=\dfrac{1}{m^2}\sum_{k=i+1}^{i+m+1}\sum_{l=j+1}^{j+m+1}f_{k,l}
\]

情况二:i+m>n and j+m<=n

\[f_{i,j}=\dfrac{(m-1)\sum_{l=j+1}^{j+m+1}f_{i,l}}{m^2}+\dfrac{1}{m}
\]

显然i有\(\dfrac{1}{m}\)的概率到达终点,而i有m种可能,又那么既然已经算了到达终点的概率,那么就不用在计算,所以乘以(m-1)。

情况三:i+m<=n and j+m>n

\[f_{i,j}=\dfrac{(m-1)\sum_{k=i+1}^{i+m+1}f_{k,j}}{m^2}+\dfrac{x(如果i=n-m,x=1,否则x=0)}{m}
\]

同样j有m种可能,但不能让他到达终点,那么就不用在计算,所以乘以(m-1)。

而当i在n-m这个位置时,i也有\(\dfrac{1}{m}\)的概率到达终点,有可能出现状态(n,n),由于太郎是先手,所以算太郎赢,而前面有减去了j到达终点的情况,所以加上去。

情况四:i+m>n and j+m>n

要求i赢,所以

当i第一回合就走到了n,概率为\(\dfrac{1}{m}\),

当i第一回合没有走到n,而j也不能走到n,在第二回合i走到了n概率为\(\dfrac{1}{m}(1-\dfrac{1}{m})^2\)

如果在第二回合i还是没有走到n,而j还是不能走到n,在第三回合i走到了n概率为\(\dfrac{1}{m}(1-\dfrac{1}{m})^4\)

如此类推,

\[f_{i,j}=limit_{n\to\infty}\dfrac{1}{m}+\dfrac{1}{m}(1-\dfrac{1}{m})^2+\dfrac{1}{m}(1-\dfrac{1}{m})^4+...+\dfrac{1}{m}(1-\dfrac{1}{m})^{2n}
\]

\[=\dfrac{1}{m}(1+(1-\dfrac{1}{m})^2+(1-\dfrac{1}{m})^4+...)+(1-\dfrac{1}{m})^{2n}
\]

等比数列求和

\[=\dfrac{1}{m}\dfrac{1*[1-(1-\dfrac{1}{m})^{2n}]}{1-(1-\dfrac{1}{m})^2}
\]

因为数列的公比小于1,\([1-(1-\dfrac{1}{m})^{2n}]\)无限趋近于1,所以

\[=\dfrac{1}{m}\dfrac{1}{1-(1-\dfrac{1}{m})^2}
\]

解得

\[f_{i,j}=\dfrac{m}{2m-1}
\]

但是这样是\(O(n^4)\)的,用矩阵后缀和优化,变成\(O(n^2)\)。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const int maxlongint=2147483647;
const int mo=1000000007;
const int N=2005;
using namespace std;
double f[N][N],n,m,x,y;
double val(int x1,int y1,int x2,int y2)
{
return f[x1][y1]-f[x1][y2]-f[x2][y1]+f[x2][y2];
}
int main()
{
scanf("%lf%lf%lf%lf",&n,&m,&x,&y);
for(int i=n;i>=1;i--)
for(int j=n;j>=1;j--)
{
f[i][j]=f[i+1][j]+f[i][j+1]-f[i+1][j+1];
if(i==n)
{
f[i][j]++;
continue;
}
if(j==n) continue;
if(i+m>n && j+m>n)
f[i][j]+=m/(2*m-1);
else
if(i+m>n)
f[i][j]+=val(i,j+1,i+1,j+m+1)*(m-1)/m/m+1/m;
else
if(j+m>n)
f[i][j]+=(m-1)*val(i+1,j,i+1+m,j+1)/m/m+(i==n-m)/m/m;
else
f[i][j]+=val(i+1,j+1,i+m+1,j+m+1)/(m*m); }
printf("%.6lf",val(x,y,x+1,y+1));
}

【NOIP2012模拟10.31】掷骰子的更多相关文章

  1. 【JZOJ4835】【GDOI2017模拟10.31】量化交易

    题目描述 数据范围 解法 贪心: 从左往右枚举,设枚举到元素为x,并维护一个堆: 设此时堆顶元素为y, 如果x大于y,那么x可以与y产生差价,立即将差价贡献给答案. 如果y之前已经和其他元素z产生过差 ...

  2. 【NOIP2012模拟10.25】旅行

    题目 给定一个n行m列的字符矩阵,'.'代表空地,'X'代表障碍.移动的规则是:每秒钟以上下左右四个方向之一移动一格,不能进入障碍. 计算:在空地中随机选择起点和终点(可以重合,此时最短耗时为0),从 ...

  3. 【NOIP2012模拟10.25】剪草

    题目 有N棵小草,编号0至N-1.奶牛Bessie不喜欢小草,所以Bessie要用剪刀剪草,目标是使得这N棵小草的高度总和不超过H.在第0时刻,第i棵小草的高度是h[i],接下来的每个整数时刻,会依次 ...

  4. 【NOIP2012模拟10.25】单元格

    题目 在一个R行C列的表格里,我们要选出3个不同的单元格.但要满足如下的两个条件: (1)选中的任意两个单元格都不在同一行. (2)选中的任意两个单元格都不在同一列. 假设我们选中的单元格分别是:A, ...

  5. LeetCode 1223. 掷骰子模拟 Dice Roll Simulation - Java - DP

    题目链接:1223. 掷骰子模拟 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数. 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[ ...

  6. Python绘制直方图 Pygal模拟掷骰子

    #coding=utf-8 from random import randint class Die(): """骰子类""" def __ ...

  7. Python 使用matplotlib模块模拟掷骰子

    掷骰子 骰子类 # die.py 骰子类模块 from random import randint class Die(): """骰子类""&quo ...

  8. 使用python实现模拟掷骰子数据分析

    Data:2020/4/8 主题:模拟实现掷骰子数据分析 编译环境:pycharm 库:pygal 说明: code 1:创建一个掷骰子类对象,类方法获得掷骰子随机数1-6,默认6个面,模拟20次将结 ...

  9. Python Tkinter小实例——模拟掷骰子

    什么是Tkinter? Tkinter 是 Python 的标准 GUI 库.Python 使用 Tkinter 可以快速的创建 GUI 应用程序. 由于 Tkinter 是内置到 python 的安 ...

随机推荐

  1. dapper 分页根据时间条件查询时中的一个坑

    当数据库中数据很多的时候,这样写,查询速度会很慢. db.Query<AuditLogModel>(queryStr, searchModel);// 应该这样写 var logDatas ...

  2. Prometheus存储模型分析

    Prometheus是时下最为流行的开源监控解决方案,我们可以很轻松地以Prometheus为核心快速构建一套包含监控指标的抓取,存储,查询以及告警的完整监控系统.单个的Prometheus实例就能实 ...

  3. Cocos2d-X多线程(1) 在cocos2d-x中使用多线程

    教科书上说:进程是资源分配的最小单位,线程是CPU调度的最小单位. 进程是程序在计算机上的一次执行活动.直观的讲就是会产生一个pid. int main() {     //业务逻辑代码     re ...

  4. mariadb数据库基础

    1.数据库介绍 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们可以通过数据库提供的多种方法来管理数据库里的数据 ...

  5. SpringBoot项目集成cas单点登录

    添加依赖 添加cas client依赖 <dependency> <groupId>net.unicon.cas</groupId> <artifactId& ...

  6. HDU 1069 Monkey and Banana (动态规划、上升子序列最大和)

    Monkey and Banana Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  7. spring boot-12.Servlet 容器

    1.spring boot 默认使用的是嵌入式的Servlet容器,spring-boot-starter-web 依赖了spring-boot-satrter-tomcat就是引入了嵌入式的tomc ...

  8. Fescar使用(资料)

    fescar源码走读1:业务调用方 https://zhuanlan.zhihu.com/p/54659540   fescar源码走读2:fescar服务端 https://zhuanlan.zhi ...

  9. HDU 1401 Solitaire 双向DFS

    HDU 1401 Solitaire 双向DFS 题意 给定一个\(8*8\)的棋盘,棋盘上有4个棋子.每一步操作可以把任意一个棋子移动到它周围四个方向上的空格子上,或者可以跳过它四个方向上的棋子(就 ...

  10. centos7搭建单机redis5.0

    目录 1. redis初步安装 2. 配置 3. 设置开机启动(centos6) 3.1 编写启动脚本 3.2 设置权限 3.3 启动测试 3.4 设置开机自启动 4. 设置开机启动(centos7) ...