乒乓球与羽毛球不同发球规则下选手的胜率——概率论+程序分析
1.当第一个选手具有发球权,如果第一个选手赢了,第一个选手得一分,如果第一个选手输了,第二个选手具有发球权,而不会得分
2.赢的人发球
3.每两球换一个人发球
每种情况分是否有两分拉锯战,共六种情况,其中第一种情况对发发球者有较大的优势;第二种情况有优势,但优势不大;第三种情况(赢t球胜),当t为奇数,且有拉锯战时,两选手胜率相同。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main() 5 { 6 double f[100][100][2],win[50]={0},lose[50]={0},p,q,pp,qq; 7 int t,x,y,i; 8 //当第一个选手具有发球权,如果第一个选手赢了,第一个选手得一分, 9 //如果第一个选手输了,第二个选手具有发球权,而不会得分 10 //如果下一球第二个选手赢了,他才会得到一分, 11 //相反,如果第一个选手赢了,他重新得到发球权,而不会得分 12 //第二个选手具有发球权,同理…… 13 14 //由第一个选手先发球,赢球的人发球,选手满t分赢,没有两分拉锯战 15 scanf("%lf%lf",&p,&q); 16 pp=p; 17 qq=q; 18 /* 19 Q=p+(1-p)*(1-q)*p+(1-p)*(1-q)*(1-p)*(1-q)*q+…… 20 =p*[1+(1-p)(1-q)+((1-p)(1-q))^2+……] 21 设R=1+(1-p)(1-q)+((1-p)(1-q))^2+…… 22 设t=(1-p)(1-q) 23 即R=1+t+t^2+…… 24 tR=t+t^2+t^3+…… 25 (1-t)R=1-t^n=1 26 R=1/(1-t) 27 Q=p/[1-(1-p)(1-q)]=p/(-p*q+p+q) 28 */ 29 p=pp/(-pp*qq+pp+qq); 30 q=qq/(-pp*qq+pp+qq); 31 //f[x][y][r]:x代表第一个选手赢球的数目,y代表第二个选手赢球的数目 32 //r代表最近的一个球由谁赢,0代表第一个选手赢,1代表第二个选手赢 33 f[1][0][0]=p; 34 f[1][0][1]=0; 35 f[0][1][1]=1-p; 36 f[0][1][0]=0; 37 for (t=2;t<100;t++) 38 for (x=0;x<=t;x++) 39 { 40 y=t-x; 41 if (x==0) 42 f[x][y][0]=0; 43 else 44 //x:y,最近一个球第一个选手赢,代表上次比分为x-1:y 45 //若上一次第一个选手赢,则这一次赢的概率为p 46 //若上一次第二个选手赢,则这一次赢的概率为1-q 47 f[x][y][0]=f[x-1][y][0]*p+f[x-1][y][1]*(1-q); 48 if (y==0) 49 f[x][y][1]=0; 50 else 51 //x:y,最近一个球第二个选手赢,代表上次比分为x:y-1 52 //若上一次第一个选手赢,则这一次赢的概率为1-p 53 //若上一次第二个选手赢,则这一次赢的概率为q 54 f[x][y][1]=f[x][y-1][0]*(1-p)+f[x][y-1][1]*q; 55 } 56 for (t=3;t<50;t++) 57 { 58 x=t*2-1; 59 //等同于打t*2-1分,分数在t分及以上则赢 60 for (i=0;i<t;i++) 61 win[t]+=(f[x-i][i][0]+f[x-i][i][1]); 62 //for (i=0;i<t;i++) 63 // lose[t]+=(f[i][x-i][0]+f[i][x-i][1]); 64 //printf("%d score: %.4lf %.4lf\n",t,win[t],lose[t]); 65 printf("%d score: %.4lf\n",t,win[t]); 66 } 67 return 0; 68 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main() 5 { 6 double f[100][100][2],win[50]={0},lose[50]={0},p,q,pp,qq,u,v,uu,vv; 7 int t,x,y,i; 8 //当第一个选手具有发球权,如果第一个选手赢了,第一个选手得一分, 9 //如果第一个选手输了,第二个选手具有发球权,而不会得分 10 //如果下一球第二个选手赢了,他才会得到一分, 11 //相反,如果第一个选手赢了,他重新得到发球权,而不会得分 12 //第二个选手具有发球权,同理…… 13 14 //由第一个选手先发球,赢球的人发球,选手满t分赢,有两分拉锯战 15 scanf("%lf%lf",&p,&q); 16 pp=p; 17 qq=q; 18 /* 19 Q=p+(1-p)*(1-q)*p+(1-p)*(1-q)*(1-p)*(1-q)*q+…… 20 =p*[1+(1-p)(1-q)+((1-p)(1-q))^2+……] 21 设R=1+(1-p)(1-q)+((1-p)(1-q))^2+…… 22 设t=(1-p)(1-q) 23 即R=1+t+t^2+…… 24 tR=t+t^2+t^3+…… 25 (1-t)R=1-t^n=1 26 R=1/(1-t) 27 Q=p/[1-(1-p)(1-q)]=p/(-p*q+p+q) 28 */ 29 p=pp/(-pp*qq+pp+qq); 30 q=qq/(-pp*qq+pp+qq); 31 //f[x][y][r]:x代表第一个选手赢球的数目,y代表第二个选手赢球的数目 32 //r代表最近的一个球由谁赢,0代表第一个选手赢,1代表第二个选手赢 33 f[1][0][0]=p; 34 f[1][0][1]=0; 35 f[0][1][1]=1-p; 36 f[0][1][0]=0; 37 for (t=2;t<100;t++) 38 for (x=0;x<=t;x++) 39 { 40 y=t-x; 41 if (x==0) 42 f[x][y][0]=0; 43 else 44 //x:y,最近一个球第一个选手赢,代表上次比分为x-1:y 45 //若上一次第一个选手赢,则这一次赢的概率为p 46 //若上一次第二个选手赢,则这一次赢的概率为1-q 47 f[x][y][0]=f[x-1][y][0]*p+f[x-1][y][1]*(1-q); 48 if (y==0) 49 f[x][y][1]=0; 50 else 51 //x:y,最近一个球第二个选手赢,代表上次比分为x:y-1 52 //若上一次第一个选手赢,则这一次赢的概率为1-p 53 //若上一次第二个选手赢,则这一次赢的概率为q 54 f[x][y][1]=f[x][y-1][0]*(1-p)+f[x][y-1][1]*q; 55 } 56 for (t=3;t<50;t++) 57 { 58 //不用拉锯战 59 for (i=0;i<=t-2;i++) 60 win[t]+=f[t][i][0]; 61 // for (i=0;i<=t-2;i++) 62 // lose[t]+=f[i][t][1]; 63 64 //要拉锯战 65 u=f[t-1][t-1][0]; 66 v=f[t-1][t-1][1]; 67 68 for (i=1;i<=50;i++) 69 { 70 //赢两球 71 win[t]+=u*p*p+v*(1-q)*p; 72 // lose[t]+=v*q*q+u*(1-p)*q; 73 uu=u; 74 vv=v; 75 //继续拉锯战(赢一球,输一球) 76 //第一个选手需输+赢 77 u=uu*(1-p)*(1-q)+vv*q*(1-q); 78 //第一个选手需赢+输 79 v=uu*p*(1-p)+vv*(1-q)*(1-p); 80 } 81 // printf("%d score: %.4lf %.4lf\n",t,win[t],lose[t]); 82 printf("%d score: %.4lf\n",t,win[t]); 83 } 84 return 0; 85 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main() 5 { 6 double f[100][100][2],win[50]={0},lose[50]={0},p,q; 7 int t,x,y,i; 8 //第一个选手发球赢的概率为p, 9 //第二个选手发球赢的概率为q 10 //由第一个选手先发球,赢球的人发球,选手满t分赢,没有两分拉锯战 11 scanf("%lf%lf",&p,&q); 12 //f[x][y][r]:x代表第一个选手赢球的数目,y代表第二个选手赢球的数目 13 //r代表最近的一个球由谁赢,0代表第一个选手赢,1代表第二个选手赢 14 f[1][0][0]=p; 15 f[1][0][1]=0; 16 f[0][1][1]=1-p; 17 f[0][1][0]=0; 18 for (t=2;t<100;t++) 19 for (x=0;x<=t;x++) 20 { 21 y=t-x; 22 if (x==0) 23 f[x][y][0]=0; 24 else 25 //x:y,最近一个球第一个选手赢,代表上次比分为x-1:y 26 //若上一次第一个选手赢,则这一次赢的概率为p 27 //若上一次第二个选手赢,则这一次赢的概率为1-q 28 f[x][y][0]=f[x-1][y][0]*p+f[x-1][y][1]*(1-q); 29 if (y==0) 30 f[x][y][1]=0; 31 else 32 //x:y,最近一个球第二个选手赢,代表上次比分为x:y-1 33 //若上一次第一个选手赢,则这一次赢的概率为1-p 34 //若上一次第二个选手赢,则这一次赢的概率为q 35 f[x][y][1]=f[x][y-1][0]*(1-p)+f[x][y-1][1]*q; 36 } 37 38 for (t=3;t<50;t++) 39 { 40 x=t*2-1; 41 //等同于打t*2-1分,分数在t分及以上则赢 42 for (i=0;i<t;i++) 43 win[t]+=f[x-i][i][0]+f[x-i][i][1]; 44// for (i=0;i<t;i++) 45// lose[t]+=f[i][x-i][0]+f[i][x-i][1]; 46 // printf("%d score: %.4lf %.4lf\n",t,win[t],lose[t]); 47 printf("%d score: %.4lf\n",t,win[t]); 48 } 49 return 0; 50 } 51 //prove that if p=q , both the two competitor have the same rate of winning
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main() 5 { 6 double f[100][100][2],win[50]={0},lose[50]={0},p,q,u,v,uu,vv; 7 int t,x,y,i; 8 //第一个选手发球赢的概率为p, 9 //第二个选手发球赢的概率为q 10 //由第一个选手先发球,赢的人发球,选手满t分赢,有两分拉锯战 11 //直到一方赢另一方两分才结束 12 scanf("%lf%lf",&p,&q); 13 //f[x][y][r]:x代表第一个选手赢球的数目,y代表第二个选手赢球的数目 14 //r代表最近的一个球由谁赢,0代表第一个选手赢,1代表第二个选手赢 15 f[1][0][0]=p; 16 f[1][0][1]=0; 17 f[0][1][1]=1-p; 18 f[0][1][0]=0; 19 for (t=2;t<100;t++) 20 for (x=0;x<=t;x++) 21 { 22 y=t-x; 23 if (x==0) 24 f[x][y][0]=0; 25 else 26 //x:y,最近一个球第一个选手赢,代表上次比分为x-1:y 27 //若上一次第一个选手赢,则这一次赢的概率为p 28 //若上一次第二个选手赢,则这一次赢的概率为1-q 29 f[x][y][0]=f[x-1][y][0]*p+f[x-1][y][1]*(1-q); 30 if (y==0) 31 f[x][y][1]=0; 32 else 33 //x:y,最近一个球第二个选手赢,代表上次比分为x:y-1 34 //若上一次第一个选手赢,则这一次赢的概率为1-p 35 //若上一次第二个选手赢,则这一次赢的概率为q 36 f[x][y][1]=f[x][y-1][0]*(1-p)+f[x][y-1][1]*q; 37 } 38 for (t=3;t<50;t++) 39 { 40 //不用拉锯战 41 for (i=0;i<=t-2;i++) 42 win[t]+=f[t][i][0]; 43 //for (i=0;i<=t-2;i++) 44 // lose[t]+=f[i][t][1]; 45 46 //要拉锯战 47 u=f[t-1][t-1][0]; 48 v=f[t-1][t-1][1]; 49 50 for (i=1;i<=50;i++) 51 { 52 //赢两球 53 win[t]+=u*p*p+v*(1-q)*p; 54 //lose[t]+=v*q*q+u*(1-p)*q; 55 uu=u; 56 vv=v; 57 //继续拉锯战(赢一球,输一球) 58 //第一个选手需输+赢 59 u=uu*(1-p)*(1-q)+vv*q*(1-q); 60 //第一个选手需赢+输 61 v=uu*p*(1-p)+vv*(1-q)*(1-p); 62 } 63 //printf("%d score: %.4lf %.4lf\n",t,win[t],lose[t]); 64 printf("%d score: %.4lf\n",t,win[t]); 65 } 66 return 0; 67 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main() 5 { 6 double f[100][100],win[50]={0},lose[50]={0},p,q,u,v; 7 int t,x,y,i; 8 //第一个选手发球赢的概率为p, 9 //第二个选手发球赢的概率为q 10 //每两球换一个人发球,选手满t分赢,没有两分拉锯战 11 scanf("%lf%lf",&p,&q); 12 //f[x][y]:x代表第一个选手赢球的数目,y代表第二个选手赢球的数目 13 f[1][0]=p; 14 f[0][1]=1-p; 15 for (t=2;t<100;t++) 16 for (x=0;x<=t;x++) 17 { 18 y=t-x; 19 if ((t % 4==1) || (t % 4==2)) 20 { 21 u=p; 22 v=1-p; 23 } 24 else 25 { 26 u=1-q; 27 v=q; 28 } 29 30 if (x==0) 31 f[x][y]=f[x][y-1]*v; 32 else if (y==0) 33 f[x][y]=f[x-1][y]*u; 34 else 35 f[x][y]=f[x][y-1]*v+f[x-1][y]*u; 36 } 37 38 for (t=3;t<50;t++) 39 { 40 //等同于打t*2-1分,分数在t分及以上则赢 41 x=t*2-1; 42 for (i=0;i<t;i++) 43 win[t]+=f[x-i][i]; 44 for (i=0;i<t;i++) 45 lose[t]+=f[i][x-i]; 46 //printf("%d score: %.4lf %.4lf\n",t,win[t],lose[t]); 47 printf("%d score: %.4lf\n",t,win[t]); 48 } 49 return 0; 50 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main() 5 { 6 double f[100][100][2],win[50]={0},lose[50]={0},p,q,u,v; 7 int t,x,y,i; 8 //第一个选手发球赢的概率为p, 9 //第二个选手发球赢的概率为q 10 //由第一个选手先发球,每两球换一个人发球,选手满t分赢,有两分拉锯战 11 //当分数为t-1:t-1时,每一球换一个人发球,直到一方赢另一方两分才结束 12 scanf("%lf%lf",&p,&q); 13 //f[x][y][r]:x代表第一个选手赢球的数目,y代表第二个选手赢球的数目 14 //r代表最近的一个球由谁赢,0代表第一个选手赢,1代表第二个选手赢 15 f[1][0][0]=p; 16 f[1][0][1]=0; 17 f[0][1][1]=1-p; 18 f[0][1][0]=0; 19 for (t=2;t<100;t++) 20 for (x=0;x<=t;x++) 21 { 22 y=t-x; 23 //第一个选手发球 24 if ((t % 4==1) || (t % 4==2)) 25 { 26 u=p; 27 v=1-p; 28 } 29 else 30 //第二个选手发球 31 { 32 u=1-q; 33 v=q; 34 } 35 36 if (x==0) 37 f[x][y][0]=0; 38 else 39 //x:y,最近一个球第一个选手赢,代表上次比分为x-1:y 40 f[x][y][0]=(f[x-1][y][0]+f[x-1][y][1])*u; 41 if (y==0) 42 f[x][y][1]=0; 43 else 44 //x:y,最近一个球第二个选手赢,代表上次比分为x:y-1 45 f[x][y][1]=(f[x][y-1][0]+f[x][y-1][1])*v; 46 } 47 48 for (t=3;t<50;t++) 49 { 50 //不用拉锯战 51 for (i=0;i<=t-2;i++) 52 win[t]+=f[t][i][0]; 53 //for (i=0;i<=t-2;i++) 54 // lose[t]+=f[i][t][1]; 55 56 //要拉锯战 57 u=f[t-1][t-1][0]+f[t-1][t-1][1]; 58 for (i=1;i<=50;i++) 59 { 60 //赢两球 61 win[t]+=u*p*(1-q); 62 //lose[t]+=u*(1-p)*q; 63 //继续拉锯战(赢一球,输一球) 64 u=u*(p*q+(1-p)*(1-q)); 65 } 66 //printf("%d score: %.4lf %.4lf\n",t,win[t],lose[t]); 67 printf("%d score: %.4lf\n",t,win[t]); 68 } 69 return 0; 70 }