After being all out for 58 and 78 in two matches in the most prestigious tournament in the world, the coach of a certain national cricket team was very upset. He decided to make the batsmen practice a lot. But he was wondering how to make them practice, because the possibility of getting out seems completely random for them. So, he decided to keep them in practice as long as he can and told them to practice in the net until a batsman remains not-out for k1 consecutive balls. But if the batsman continues to be out for consecutive k2 balls, then the coach becomes hopeless about the batsman and throws him out of the team. In both cases, the practice session ends for the batsman. Now the coach is wondering how many balls the practice session is expected to take.
For a batsman the probability of being out in a ball is independent and is equal to p. What is the expected number of balls he must face to remain not out for k1 consecutive balls or become out in consecutive k2 balls.
Input
Input starts with an integer T (≤ 15000), denoting the number of test cases.
Each case starts with a line containing a real number p (0 ≤ p ≤ 1) and two positive integers k1 and k2 (k1 + k2 ≤ 50). p will contain up to three digits after the decimal point.
Output
For each case, print the case number and the expected number of balls the batsman will face. Errors less than 10^-2 will be ignored.
Sample Input
5
0.5 1 1
0.5 1 2
0.5 2 2
0.19 1 3
0.33 2 1
Sample Output
Case 1: 1
Case 2: 1.5
Case 3: 3
Case 4: 1.2261000000
Case 5: 1.67
大致题意:一个击球手在击球,如果他连续击了k1个球不出界,或者连续击了k2个球都出界的话,训练结束,告诉你击球出界的概率为P,问训练结束时所击球的期望数量为多少
思路:假设f(x)表示此时已经连续击球x个没有出界时到训练结束还需击球的个数,g(x)表示此时已经连续击球x个且都出界时到训练结束还需击球的个数。
易知 f(k1)=0,g(k2)=0;
f(x)=f(x+1)* (1-p)+g(1)*p+1,
g(x)=g(x+1) * p+f(1) * (1-p)+1,
经过推导,f(1)=(g(1)p+1) ((1-p)^0+(1-p)^1+…+(1-p)^(k1-1))
即 f(1)=(g(1)p+1) (1-(1-p)^(k1-1))/p
同理可得g(1)=(f(1)(1-p)+1) (1-p^(k2-1))/(1-p)
令A=1-(1-p)^(k1-1),B=1-p^(k2-1),B=1-p^(k2-1),
由上面两条公式可以解得
f(1)=(A/p+A*B/(1-p))/(1-A*B)
g(1)=(A*B/p+B/(1-p))/(1-A*B)
最后答案即为(1-p)*f(1)+p*g(1)+1
代码如下
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
#define LL long long
#define ULL unsigned long long
const double eps = 1e-9;
double kpow(double x,int n) // x^n
{
double res=1;
while(n>0)
{
if(n & 1)
res=res*x;
x=x*x;
n >>= 1;
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
double p;
int k1,k2;
for(int cas=1;cas<=T;cas++)
{
scanf("%lf%d%d",&p,&k1,&k2);
if(p<eps) printf("Case %d: %d\n",cas,k1);//考虑极端数据
else if(1-p<eps) printf("Case %d: %d\n",cas,k2);
else
{
double A=1-kpow(1-p,k1-1);
double B=1-kpow(p,k2-1);
double x1=(A*B/p+B/(1-p))/(1-A*B);//g(1)
double x2=(A/p+A*B/(1-p))/(1-A*B);//f(1)
printf("Case %d: %.7lf\n",cas,x1*p+x2*(1-p)+1);//答案即为g(1)*p+f(1)*(1-p)+1
}
}
return 0;
}