http://poj.org/problem?id=1217
题意:两个人在玩抛硬币的游戏,没回合抛两次,两次的结果不同,双方得到的分也是不同的,要求输出前20轮中,没回合A胜,B胜或是平局的概率。
算法:概率DP
分析:用dp[i][j][k] 来表示第i轮,A得的总分数为j,B得的分数是k的概率 ,用向后递推的思想就可以求解本题了。
代码:
/* POJ 1217 FOUR QUARTERS Tips : DP runtime 0ms Memory 1080K */ #include<stdio.h> #include<string.h> const double P1 = 1.0 / 2.0 ; const double P2 = 1.0 / 4.0 ; int add_a[15] = {0,1,1,2,0,0,1,-1,0,0} ; int add_b[15] = {0,0,-1,-1,1,0,0,2,0,-1} ; double p[15] = {1,P2*P2,P1*P2,P2*P2,P1*P2,P1*P1,P1*P2,P2*P2,P2*P1,P2*P2} ; double dp[21][65][65] ; void DP(){ memset(dp,0,sizeof(dp)); dp[0][20][20] = 1 ; for(int i=1;i<=20;i++){ for(int j=0;j<=60;j++){ int score1 = j-20 ; for(int k=0;k<=60;k++){ int score2 = k - 20 ; for(int st=1;st<=9;st++){ int n_s1 = score1 + add_a[st] ; int n_s2 = score2 + add_b[st] ; dp[i][n_s1+20][n_s2+20] += dp[i-1][j][k] * p[st] ; } } } } printf("Round A wins B wins Tie\n"); for(int i=1;i<=20;i++){ double a_win = 0 , b_win = 0 , tie = 0 ; for(int j=0;j<=60;j++){ for(int k=0;k<=60;k++){ if(j>k) a_win+=dp[i][j][k] ; else if(j<k) b_win += dp[i][j][k] ; else tie += dp[i][j][k] ; } } printf("%5d%10.4f%%%9.4f%%%9.4f%%\n",i,a_win*100,b_win*100,tie*100); } } int main(){ freopen("1out","w",stdout); DP() ; return 0; }