gavanwanggw

导航

hdu3076ssworld VS DDD 概率dp

//ssworld VS DDD 两个人有血量值 hp1 , hp2 
//两人掷骰子得到每一点的概率已知
//ssword赢的概率
//dp[i][j]  表示有第一个人血量为i。第二个人的血量为j第一个人赢的概率
//第一个人赢,第二个人赢 , 平局的概率为p1 , p2 , p3
//那么有dp[i][j] = p2*dp[i-1][j] + p1*dp[i][j-1] + p3*dp[i][j]
//整理可得dp[i][j] = p2/(1-p3)*dp[i-1][j] + p1/(1-p3)*dp[i][j-1] 
//特别坑的是它的血量是倒着输入的
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 2010 ;
double dp[2][maxn] ;
double p[2][6] ;
int main()
{
    //freopen("in.txt" ,"r" , stdin) ;
    //freopen("out.txt" ,"w" , stdout) ;
    int n , m ;
    while(~scanf("%d%d"  ,&m , &n))
    {
        double p3 = 0 ,p1 = 0 , p2 = 0;
        for(int i = 0;i < 2;i++)
         for(int j = 0 ;j < 6 ; j++)
             scanf("%lf" , &p[i][j]) ;
        for(int i = 0;i < 6;i++)
        {
            for(int j = 0;j < i ;j++)
            p1+= p[0][i]*p[1][j] ;
            for(int j = i+1 ;j < 6;j++)
            p2 += p[0][i]*p[1][j] ;
        }
        p3 = 1 - p1 - p2 ;
        if(p3 == 1){puts("0");continue;}
        memset(dp , 0 , sizeof(dp)) ;
        dp[0][0] = dp[1][0] = 1;
        for(int i = 1;i <= n ;i++)
          for(int j = 1;j <= m;j++)
          dp[i%2][j] = p2/(1-p3)*dp[(i-1)%2][j] + p1/(1-p3)*dp[i%2][j-1] ;
        printf("%.6lf\n" , dp[n%2][m]) ;
    }
    return  0 ;
}





posted on 2017-05-05 14:29  gavanwanggw  阅读(170)  评论(0编辑  收藏  举报