【NOIP 模拟题】掷骰子(dp)

原创 2016年08月28日 14:43:04

掷骰子(dice.cpp)

【问题描述】

    太郎和一只兔子正在玩一个掷骰子的游戏。有一个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格,接下来是太郎掷骰子,太郎想知道他赢得比赛的概率是多少。

【问题输入】

    一行4格整数N、M、x、y。

【问题输出】

    一行一个小数,表示太郎获胜的概率(保留六位小数)

【样例输入】

    10 6 1 1

【样例输出】

    0.541725

【数据范围】

    30%的数据:10<=N<=100;

    100%的数据:10<=N<=2000,M,x,y<=n-1。

————————————————————————————————

【题解】【dp】

【f[i][j]表示A在第i格,B在第j格时,A获胜的概率。特别的:若i=n或j=n时,概率是1或0】

【分四种情况考虑:

 [1)若i+m<=n、j+m<=n,即i、j都不能一步获胜]  

      

(A从走到i+1-i+m这之间的位置的可能性都是均等的,都是1/m,同理,B从走到j+1-j+m这之间的位置的可能性都是1/m,所以每一个f[i'][j']出现的概率都是1/(m²))

【2)i+m<=n、j+m>n [A不能一步到终点,B可能一步到终点]】

  

j只有1中可能上次从n转移过来,j共有m中取值;i也有m种取值,所以共有m²种可能,再加上i这一步可以到终点的一种可能性

【3)i+m>n,j+m<=n[A可能一步到终点,B不可能一步到终点]


(这种情况下,与第2种情况相似)

【4)i+m>n,j+m>n[A、B都有可能一步到终点]】

   在这种情况下,因为有反弹,soA、B的位置只可能在[n-m+1,n]中,两人一步到终点的几率都是1/m,

    那么,A先到n的可能就是

                             

 等比数列求和:

                                

 化简得:

                                

【5)最后,还有一点,若i=n-m,当i'=j=n的概率为1】

。 

[转自: http://blog.csdn.net/lyd_7_29/article/details/52245309]

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,x,y;
double f[2010][2010];//f[i][j]表示A在第i格,B在第j格时,A获胜的概率 
inline double SUM(int x1,int y1,int x2,int y2)
{
	return (f[x1][y1]-f[x1][y2]-f[x2][y1]+f[x2][y2]);
}
int main()
{
	freopen("dice.in","r",stdin);
	freopen("dice.out","w",stdout);
	int i,j;
	scanf("%d%d%d%d",&n,&m,&x,&y);
	for(i=n;i>0;--i)
	 for(j=n;j>0;--j)
	  {
	  	f[i][j]=f[i+1][j]+f[i][j+1]-f[i+1][j+1];
	  	if(i==n||j==n) {f[i][j]+=(i==n); continue;}//有一个已到终点 
	  	if(i<=n-m&&j<=n-m) {f[i][j]+=SUM(i+1,j+1,i+m+1,j+m+1)/m/m; continue; }//A、B都不能一步到终点 
	  	if(i<=n-m&&j>n-m) {f[i][j]+=((m-1)*SUM(i+1,j,i+m+1,j+1)+(i+m==n))/m/m; continue;}//A不能一步到终点,B可能一步到终点 
	  	if(i>n-m&&j<=n-m) {f[i][j]+=((m-1)*SUM(i,j+1,i+1,j+m+1)+m)/m/m; continue; }//A可能一步到终点,B不能一步到终点 
	  	if(i>n-m&&j>n-m) {f[i][j]+=1.0*m/(2*m-1); continue;}//A、B都可能一步到终点 
	  }
	printf("%.6lf\n",SUM(x,y,x+1,y+1));
	return 0;
}


版权声明:本文为博主原创文章,转载请注明出处:http://blog.csdn.net/reverie_mjp

NOIP2016[换教室] 期望概率DP

NOIP2016 换教室 期望概率DP
  • qq_37321281
  • qq_37321281
  • 2017年07月31日 14:55
  • 209

【NOIP 模拟题】[T2]宝藏(树形dp)

饮月千尺,寂夜成相思
  • reverie_mjp
  • reverie_mjp
  • 2016年11月14日 20:45
  • 259

[noip模拟赛]二进制(dp)

从尘土里来的人,能理解开怀大笑背后的酸楚,也知道幽默是面对不完美人生的最好办法。...
  • Clove_unique
  • Clove_unique
  • 2016年08月24日 14:36
  • 570

NOIP模拟题[贪心][DP][数论]

改程序之前,写程序之前,确保自己理解了,不然效率会很低。 写程序少用复制黏贴,容易细节出错,不好调试。 T1: 题意: 给定两字符串,判断B串是否是A串的字串且输出B串每个字母的匹配位置字典序...
  • SindarDawn
  • SindarDawn
  • 2016年11月02日 17:28
  • 437

NOIP模拟题 [递推][DP][搜索]

T1: 题意: 要求将1-n的数排成两列,使得两列数的个数相等且都递增,还要求其中一列比另一列对应位置上的数大。 分析: 两个方法: 1.先写个暴力打表找规律,因为反正也要写对拍。 2.分...
  • SindarDawn
  • SindarDawn
  • 2016年11月13日 22:00
  • 530

【NOIP2000】方格取数 DP优化 解题报告

问题 L(1137): 【NOIP2000】方格取数 时间限制: 1 Sec  内存限制: 64 MB 题目描述 设有N*N的方格图,我们将其中的某些方格中填入正整数,而其他的方格中则放入数...
  • u013675643
  • u013675643
  • 2016年07月05日 09:35
  • 591

全排列(洛谷1061 Jam的计数法or NOIP 2006 普及组 第三题)

Jam是个喜欢标新立异的科学怪人。他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩。 在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字母按原...
  • u013672056
  • u013672056
  • 2017年07月27日 20:36
  • 91

护卫队 解题报告

护卫队 【问题描述】 护卫车队在一条单行的街道前排成一队,前面河上是一座单行的桥。因为街道是一条单行道,所以任何车辆都不能超车。桥能承受一个给定的最大承载量。为了控制桥上的交通,桥两边各站一个指挥...
  • Clove_unique
  • Clove_unique
  • 2015年08月24日 11:26
  • 902

NOIP2017游记+题解+标程

NOIP2017提高组 NOIP2017提高组题解 洛谷题目链接 程序
  • u011056504
  • u011056504
  • 2017年11月13日 12:24
  • 426

NOIP2016考前做题(口胡)记录

NOIP以前可能会持续更新写在前面NOIP好像马上就要到了,感觉在校内训练里面经常被虐有一种要滚粗的感觉(雾。不管是普及组还是提高组,我都参加了好几年了,结果一个省一都没有,今年如果还没有的话感觉就真...
  • qq_33442848
  • qq_33442848
  • 2016年10月29日 17:38
  • 862
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【NOIP 模拟题】掷骰子(dp)
举报原因:
原因补充:

(最多只允许输入30个字)