題意:
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