题意:
两人比赛(定义成甲和乙),两人一开始分别有n和m个糖果,玩24点,每赢一局从对方那里获得一个糖果,谁先没有糖果谁输。两个人能解除24点的概率分别为a和b,若都解出或都没解出则为平局,不交换糖果。求甲赢的概率。
题解:
一个Markov过程的应用。详细信息链接:Markov过程-百度文库
具体Markov过程没有怎么了解,基本概念是马可夫过程的条件概率仅仅与系统的当前状态相关,而与它的过去历史或未来状态,都是独立、不相关的。
这题相当于赌徒问题的变形(只是加了平局)。
具体过程:
设0<=j<=n+m;uj为从j个糖果到达0个糖果状态先于到达n+m个糖果状态的概率。
那么uj=p*u(j+1)+q*u(j-1)+(1-p-q)*uj(p为甲胜的概率,q为乙胜的概率,这个公式的意思是j状态可以转到的状态)
(p+q)uj=p*u(j+1)+q*u(j-1)化简后即跟赌徒问题一样了。(其中p=a*(1-b),q=b*(1-a))
之后的情况见下图:
赌徒输光问题:
代码:
#include <cstdio> #include <cstdlib> #include <cmath> #include <ctime> #include <cstring> #include <iostream> #include <algorithm> #include <map> #include <set> #include <vector> #include <queue> #include <iomanip> using namespace std; const double eps=1e-12; int main() { int n,m; double p,q; while(scanf("%d%d%lf%lf",&n,&m,&p,&q)!=EOF) { double ans,r; if(m==0)ans=1;//如果m=0,那么即使n=0也会赢 else if(n==0||p==0||q==1)ans=0; else { r=q*(1-p)/(p*(1-q));//Speakless胜的概率p*(1-q) if(fabs(r-1.0)<eps)ans=1.0*n/(n+m);//胜率相等 else ans=(1-pow(r,n))/(1-pow(r,n+m)); } printf("%.2f\n",ans); } return 0; } /* Markov过程(马尔科夫过程) */