lightoj 1408 Batting Practice (概率问题,求期望,推公式)

题意:一个人若连续进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;
}
View Code
原文地址:https://www.cnblogs.com/chenxiwenruo/p/3636857.html