HDU 1204 糖果大战[Markov过程]

题意:

生日Party结束的那天晚上,剩下了一些糖果,Gandon想把所有的都统统拿走,Speakless于是说:“可以是可以,不过我们来玩24点,你不是已经拿到了一些糖果了吗?这样,如果谁赢一局,就拿走对方一颗糖,直到拿完对方所有的糖为止。”如果谁能算出来而对方算不出来,谁就赢,但是如果双方都能算出或者都不能,就算平局,不会有任何糖果的得失。 
Speakless是个喜欢提前想问题的人,既然他发起了这场糖果大战,就自然很想赢啦(不然可就要精光了-_-)。现在他需要你的帮忙,给你他每局赢的概率和Gardon每局赢的概率,请你给出他可能获得这场大战胜利的概率。

分析:

Markov过程(马尔科夫过程)。
f[i]表示手上有i个糖果时,最终要赢得n个糖果的概率。要达到他有三种情况,
1. 赢得一个糖果, 概率是p(1-q), 这是下一个时刻t+1 G就有了i+1个糖果.
2. 输掉比赛, 在下一个时刻变成了i-1个糖果, 概率是q(1-p).
3. 打成平手, 下一个时刻还有i个糖果, 概率是1-p(1-q)-q(1-p).
得到如下公式:
 fi=p(1-q)*fi+1+q(1-p)*fi-1+(1-p(1-q)-q(1-p))*fi
等比数列化简:
fn=(1+K+K2+...+Kn-1)/(1+K+K2+...+Km+n-1)  其中k=q*(1-p)/p*(1-q)
特殊情况为q=1,这个时候是等差数列。
#include <stdio.h>
#include <string.h>
int main()
{
    int n, m;
    int i, j;
    double p,q,a,b;
    double s;
    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;
        }
        a = q*(1-p);
        b = p*(1-q);
        s = a/b;
        double c1=1;
        double en=1;
        if (a==b)
        {
            c1 = 1.0/(1.0*(n+m));
            en = c1*n;
            printf("%.2lf\n",en);
            continue;
        }
        for (i=1; i<=n+m; i++)
            c1 *= s;
        c1 = (1-s)/(1-c1);
        for (i=1; i<=n; i++)
            en *= s;
        en = (1-en)*c1/(1-s);
        printf("%.2lf\n",en);
    }
    return 0;
}

 

posted @ 2013-01-29 12:07  'wind  阅读(525)  评论(0编辑  收藏  举报