1. Title link:
LightOJ-1408
2. The main idea of the topic:
There is a probability of p for each pitch. If you make k1 consecutive shots or consecutive k2 shots, the game is over.
Find the expectations for the number of pitches.
3. Analysis:
f[i]: I have made i consecutive shots, the expected number of shots before the end of the game.
g[i]: It has been pitched i times in a row, the expected number of pitches before the end of the game.
Easy to get transfer equation:
f[i] = (1 - p) * f[i + 1] + p * g[1] + 1.
g[i] = p * g[i + 1] + (1 - p) * f[1] + 1.
After simple iteration:
Combine the two types to get:
Solve f[1] and back with it to get g[1].
The final answer ans = qf[1] + pg[1] + 1.
4. Code implementation:
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
double quick(double a, int b)
{
double sum = 1.0;
while(b)
{
if(b & 1) sum *= a;
a *= a;
b >>= 1;
}
return sum;
}
int main()
{
int T;
scanf("%d", &T);
for(int ca = 1; ca <= T; ++ca)
{
double p; int k1, k2;
scanf("%lf %d %d", &p, &k1, &k2);
if(fabs(p - 0.0) < eps) printf("Case %d: %d\n", ca, k1);
else if(fabs(p - 1.0) < eps) printf("Case %d: %d\n", ca, k2);
else
{
double q = 1.0 - p;
double pk = quick(p, k2 - 1), qk = quick(q, k1 - 1);
double f1 = (1.0 - qk) * ((1.0 - pk) / q + 1.0 / p) / (1.0 - (1.0 - qk) * (1.0 - pk));
double g1 = (q * f1 + 1.0) * (1.0 - pk) / (1.0 - p);
double ans = q * f1 + p * g1 + 1.0;
printf("Case %d: %f\n", ca, ans);
}
}
return 0;
}