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