现在的位置: 首页 > 综合 > 正文

POJ FOUR QUARTERS

2014年01月30日 ⁄ 综合 ⁄ 共 1056字 ⁄ 字号 评论关闭

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;
}

抱歉!评论已关闭.