hdu_1204 糖果大战 (概率论)

http://acm.hdu.edu.cn/showproblem.php?pid=1204

分析:

1) 特殊情况(注意顺序)

    n=0                                           lose

    m=0(此时已排除 n=0 情况)  win

    p=0&&q==1                            lose

    p=1&&q=0                               win

    p=q                                          n/(n+m)

2) 一般情况(markov  chain model)

    f(i)  : Speakless已经得第i个糖果的概率;

    win:p(1-q)——> f(i+1);

    lose:q(1-p)——> f(i-1);

    平局:1-p(1-q)-q(1-p) —— f(i);

 f(i) = p(1-q)*f(i+1) + q(1-p)*f(i-1) + (1-p(1-q)-q(1-p))*f(i)

化为: p(1-q) * (f(i+1)-f(i)) = q(1-p) * (f(i)-f(i-1))

令 g(i)=f(i)-f(i-1) , t = g(i+1) / g(i) =  ( q(1-p) ) / ( p(1-q) )  (等比数列公比)

递推式: g(i) = g(i-1)* t 

g(1) = f(1)-f(0)
g(2) = f(2)-f(1)
...
g(n) = f(n)-f(n-1)
...
g(n+m) = f(n+m)-f(n+m-1)

将上面的各式相加:g(1)+g(2)+...+g(n+m) = f(n+m)-f(0)=1

因为:  f(0)=0 ,f(n+m)=1

所以 : g(1)+g(2)+...+g(n) = f(1)*(1-t^(n))/(1-t)=f(n)                            (1)
              g(1)+g(2)+...+g(n+m) = f(1)*(1-t^(n+m))/(1-t)=1                     (2)


(1)/(2)得 :f(n) = (1-t^n) / (1-t^(m+n))

   

代码:

#include 
#include 
#include 
using namespace std;

int main()
{
    int n,m;
    double p,q;
    double t,ans;
    while(scanf("%d%d%lf%lf",&n,&m,&p,&q)!=EOF){
        if(n==0)     {printf("0.00\n"); continue;}
        if(m==0)     {printf("1.00\n");continue;}
        if(p==0 || q==1) {printf("0.00\n");continue;}
        if(q==0 || p==1) {printf("1.00\n");continue;}
        if(p==q)         ans= 1.0*n/(m+n);
        else{
            t=q*(1-p) / (p*(1-q));
            ans= (1.0-pow(t,n)) / (1.0 -pow(t,n+m));
        }
        printf("%.2f\n",ans);
    }
    return 0;
}


 

你可能感兴趣的:(概率论)