题意:
A、B俩游戏者,每轮俩人分别抛俩硬币,然后根据结果结算该轮得分:
A胜B即A的点数大于B的点数。
然后输出20轮内A赢B、B赢A以及打平的概率。
解答:
这题和一般的概率题不同,二者的点数是不独立的,所以要用一个pair和map存储他们的概率。
结合代码来说吧
1 # include <cstdio>
2 # include <cstring>
3 using namespace std;
4 # include <map>
5 # define encode(a,b) (((a)<<6)|(b))
6 # define getp1(a) ((a)>>6)
7 # define getp2(a) ((a)&63)
8 int main()
9 {
10 double res[21][2];
11 //p[i][j],A得到i-1分,B得到j-1分的概率,以后为了处理方便,可以将得-1,0,1,2分看作得0,1,2,3分
12 double p[4][4]={{0,0,0,1.0/16},{1.0/16,3.0/8,1.0/8,0},{1.0/8,3.0/16,0,0},{1.0/16,0,0,0}};
13 memset(res,0,sizeof(res));
14 map<int,double> table[21];
15 table[0][encode(0,0)]=1.0;//边界情况:A得0分,B得0分的概率为1
16 for(int step=1;step<=21;step++)
17 {
18 for(map<int,double>::iterator ita=table[step-1].begin();ita!=table[step-1].end();ita++)
19 {
20 int p1=getp1(ita->first),p2=getp2(ita->first);
21 if(step!=21)
22 {
23
24 for(int i=0;i<4;i++)
25 for(int j=0;j<4;j++)
26 table[step][encode(p1+i,p2+j)]+=(ita->second)*p[i][j];//状态转移
27 }
28 if(p1<p2)//累加A输给B的概率
29 res[step-1][0]+=ita->second;
30 else if(p1==p2)//累加打平的概率
31 res[step-1][1]+=ita->second;
32 }
33 }
34 printf("Round A wins B wins Tie\n");
35 for(int i=1;i<=20;i++)//输出格式注意,如果需要在printf内输出%的话要用%%
36 printf("%5d%10.4f%%%9.4f%%%9.4f%%\n",i,(1-res[i][0]-res[i][1])*100,res[i][0]*100,res[i][1]*100);
37 return 0;
38 }
39