题意:
击球训练中, 你击中一个球的概率为p,连续击中k1个球, 或者连续击空k2个球, 则训练结束。
求结束训练所击球次数的期望。
思路:
设f[x]为连续击中x个球, 距离结束训练所需要的期望
设g[x]为连续击空x个球, 距离结束训练所需要的期望
f[x] = p * (f[x + 1] + 1) + (1 - p) * (g[1] + 1)
g[x] = p * (f[1] + 1) + (1 - p) * (g[x + 1] + 1)
令 x = (1 - p) * (g[1] + 1)
迭代f[x] 得到f[1]的表达式为:
f[1] = p^(k - 2) * x + p^(k - 3) * x + ... + p ^ 0 * x。
f[1] = x * ( (1 - p ^ (k - 1))/ (1 - p))
一样的解法,求出g[1]的表达式,再将f[1]代进g[1] 的表达式, 解得g[1].
再将g[1]反代入f[1]的表达式, 解得f[1]。
最后答案为 ans = p * (f[1] + 1) + (1 - p) * (g[1] + 1)
代码:
1 #include <cmath>
2 #include <cstdio>
3 #include <cstring>
4 #include <cstdlib>
5 #include <ctime>
6 #include <set>
7 #include <map>
8 #include <list>
9 #include <queue>
10 #include <string>
11 #include <vector>
12 #include <fstream>
13 #include <iterator>
14 #include <iostream>
15 #include <algorithm>
16 using namespace std;
17 #define LL long long
18 #define INF 0x3f3f3f3f
19 #define MOD 1000000007
20 #define eps 1e-6
21 #define MAXN 1000000
22 #define MAXM 100
23 #define dd cout<<"debug"<<endl
24 #define p(x) printf("%d\n", x)
25 #define pd(x) printf("%.7lf\n", x)
26 #define k(x) printf("Case %d: ", ++x)
27 #define s(x) scanf("%d", &x)
28 #define sd(x) scanf("%lf", &x)
29 #define mes(x, d) memset(x, d, sizeof(x))
30 #define do(i, x) for(i = 0; i < x; i ++)
31 #define dod(i, x, l) for(i = x; i >= l; i --)
32 #define doe(i, x) for(i = 1; i <= x; i ++)
33 double p;
34 int k1, k2;
35 double qpow(double x, int k)
36 {
37 double res = 1.0;
38 while(k)
39 {
40 if(k & 1) res *= x;
41 x *= x;
42 k >>= 1;
43 }
44 return res;
45 }
46
47 int main()
48 {
49 int T;
50 int kcase = 0;
51 scanf("%d", &T);
52 while(T --)
53 {
54 scanf("%lf %d %d", &p, &k1, &k2);
55 if(p == 0.000)
56 printf("Case %d: %d\n", ++ kcase, k1);
57 else if(p == 1.000)
58 printf("Case %d: %d\n", ++ kcase, k2);
59 else
60 {
61 double q = 1.0 - p;
62 double x1 = 1.0 - qpow(p, k2 - 1);
63 double x2 = 1.0 - qpow(q, k1 - 1);
64 double f = x1 * x2 / q + x2 / p;
65 f = f / (1 - x1 * x2);
66 double g = q * f * x1 / q + x1 / q;
67 double ans = q * f + p * g + 1.0;
68 printf("Case %d: %.3lf\n", ++ kcase, ans);
69 }
70 }
71 return 0;
72 }