hdu 3076 ssworld VS DDD 概率dp

来源:互联网 发布:自制点播软件 编辑:程序博客网 时间:2024/05/17 03:13

题意: A,B掷骰子,对于每一次点数大者胜,平为和,A先胜了m次A赢,B先胜了n次B赢。

WA了那么多次这题目数据是错的,两个人的血量弄错了,输入的 A的血量其实是B的,输入B的其实是A的,由于有平局现象的干扰,所以一开始先把平局包括进去 的 A赢的概率B赢的概率都算出来,然后减去以后就是平局的概率(这个地方要特别注意一下,因为dp记录的是赢了几次那么乘以概率的时候只有输赢不能算进去平局),再在已经除去平局的情况里 算一下A赢的概率,B赢得概率计算出来,这样就可以计算了,

假设方程dp[i][j]代表 A赢了j次B赢了i次的概率,然后状态转移就比较简单了 :

dp[i][j] += dp[i][j - 1] * a_win;
dp[i][j] += dp[i - 1][j] * b_win;

然后就是需要注意的是 B至多赢n-1次,而A必须恰好赢m次,

一开始没注意,当A已经赢了以后第二个状态转移已经不需要再加了,一开始没注意,第二个状态转移多加了一次

还有这破题目,数组要是开dp[2050][2050]就会MLE....必须差不多刚好2005 * 2005



Problem Description
One day, sssworld and DDD play games together, but there are some special rules in this games.
They both have their own HP. Each round they dice respectively and get the points P1 and P2 (1 <= P1, P2 <= 6). Small number who, whose HP to reduce 1, the same points will remain unchanged. If one of them becomes 0 HP, he loses.
As a result of technical differences between the two, each person has different probability of throwing 1, 2, 3, 4, 5, 6. So we couldn’t predict who the final winner.

 

Input
There are multiple test cases.
For each case, the first line are two integer HP1, HP2 (1 <= HP1, HP2 <= 2000), said the first player sssworld’s HP and the second player DDD’s HP.
The next two lines each have six floating-point numbers per line. The jth number on the ith line means the the probability of the ith player gets point j. The input data ensures that the game always has an end.
 

Output
One float with six digits after point, indicate the probability sssworld won the game.
 

Sample Input
5 51.000 0.000 0.000 0.000 0.000 0.0000.000 0.000 0.000 0.000 0.000 1.0005 50.000 0.000 0.000 0.000 0.000 1.0001.000 0.000 0.000 0.000 0.000 0.000
 

Sample Output
0.0000001.000000
 

Source
2009 Multi-University Training Contest 17 - Host by NUDT 
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;double dp[2000 + 5][2000 + 5];int main(){    int n,m;    double a[7],b[7];    double a_win,b_win;    while(~scanf("%d %d",&n,&m))    {        for(int i=0; i<6; i++)            scanf("%lf",&a[i]);        for(int i=0; i<6; i++)            scanf("%lf",&b[i]);        a_win=0;        b_win=0;        for(int i=1; i<6; i++)            for(int j=0; j<i; j++)                a_win+=a[i]*b[j];        for(int i=1; i<6; i++)            for(int j=0; j<i; j++)                b_win+=b[i]*a[j];        double p=a_win+b_win;        a_win/=p;        b_win/=p;        memset(dp,0,sizeof(dp));        dp[0][0]=1;        for(int j=0; j<n; j++)            for(int i=0; i<m; i++)            {                if(i+j>0)                {                    if(i>0)                        dp[i][j]+=dp[i-1][j]*b_win;                    if(j>0)                        dp[i][j]+=dp[i][j-1]*a_win;                }            }        double ans=0;        for(int i=0; i<m; i++)//这个地方因为有两个条件导致的第一个是当A赢了n次那么就停止了,如果上面是<=n那么就会有重复,所以用n-1最后再乘以一次赢得概率就行了            ans+=dp[i][n-1]*a_win;        if (ans>1) ans=1;        printf("%.6lf\n",ans);    }    return 0;}


0 0
原创粉丝点击