题意:一个人若连续进k1个球或连续不进k2个球,游戏结束,给出这个人不进球的概率p(注意:是不进球!!!),求到游戏结束时这个投球个数的期望。
不进球概率为p,进概率 q=1-p。
设 f[i] 表示连续 i 次不进结束的期望,t[i]表示连续 i 次进球,距离结束的期望。显然,f[k2]=t[k1]=0;
f[i] = q*(f[i+1]+1)+p*(1+t[1]) , t[i] = p*(t[i+1]+1)+q*(1+f[1]).
答案是 p*t[1]+q*f[1]+1.
然后就算t[1],f[1]
将t[1],f[1]都移到等式左边,等式右边是其余的项,然后左右都乘以q/p^i(i=0,1,...k2-2/k1-2),总共k2-1/k1-1项。
消除中间项,只剩f[1],t[1]。然后就求解二元一次方程
#include <iostream> #include <cmath> #include <string.h> #include <algorithm> #include <cstdio> using namespace std; double p,q; //击不中的概率为p,击中的概率为q int k1,k2; //连续击中k1次,连续不击中k2次 int main() { int t; int cases=0; scanf("%d",&t); while(t--){ scanf("%lf%d%d",&p,&k1,&k2); //不加下面的两个if,为WA if(p>1-1e-5) { //未击中的概率近似为1 printf("Case %d: %.5lf ",++cases,1.0*k2); continue; } else if(p<1e-5) { //未击中的概率近似为0 printf("Case %d: %.5lf ",++cases,1.0*k1); continue; } q=1-p; double a1=1-pow(q,k1-1),b1=a1/(1-q); double a2=1-pow(p,k2-1),b2=a2/(1-p); double t1=(a1*b2+b1)/(1-a1*a2),f1=a2*t1+b2; printf("Case %d: %.5lf ",++cases,p*f1+q*t1+1); } return 0; }