pku1217 FOUR QUARTERS 概率递推

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


posted on 2010-11-06 19:52 yzhw 阅读(135) 评论(0)  编辑 收藏 引用 所属分类: combination math


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

公告

统计系统

留言簿(1)

随笔分类(227)

文章分类(2)

OJ

最新随笔

搜索

积分与排名

最新评论

阅读排行榜