题意:
一个人在击球,有p的概率集中,有(1-p)的概率击不中。如果能够连续击中x次将停止,连续不集中y次也将停止。问最终停止击球时击球次数的期望。
思路:
设f[i]代表连续击中i次之后距离结束还剩的期望步数。g[i]代表连续不集中i次后距离结束的期望步数。可以列出下列方程:
{f[i]=p∗f[i+1]+(1−p)∗g[1]+1g[i]=(1−p)∗g[i+1]+p∗f[1]+1
边界条件:
{f[x]=0g[y]=0
答案:
ans=p∗f[1]+(1−p)∗g[1]
推导过程:
令:
{AB=(1−p)∗g[1]+1=p∗f[1]+1
则原式:
{f[i]g[i]=p∗f[i+1]+A=(1−p)∗g[i+1]+B
求解f[1]和g[1]:
f[1]=p∗f[2]+A=p∗(p∗f[3]+A)+A=p2∗f[3]+A∗(1+p)=px−1∗f[x]+A∗(1+p+p2+...+px−2)=0+A∗1−p1−px−1=A∗1−p1−px−1=(1−px−1)∗g[1]+1−p1−px−1.
同理 g[1]=[1−(1−p)y−1]∗f[1]+p1−(1−p)y−1
令
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧CDEF=[1−(1−p)y−1]=p1−(1−p)y−1=(1−px−1)=1−p1−px−1
则
{g[1]f[1]=C∗f[1]+D=E∗g[1]+F
求得f[1]=1−CEDE+F
g[1]=C∗f[1]+D
带入ans即可。
需要注意p=0或p=1时的情况。
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld long double
#define ull unsigned long long
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int maxn = 5e5 + 10;
const int maxm = 5e5 + 10;
const ll mod = 1e9 + 7;
const double eps = 1e-10;
ld p, x, y;
int main() {
__;
int _;
cin >> _;
for (int sce = 1; sce <= _; ++sce) {
cin >> p >> x >> y;
cout << "Case " << sce << ": ";
p = 1.0 - p;
if (p == 1.0) {
cout << x << endl;
continue;
}
if (p == 0.0) {
cout << y << endl;
continue;
}
ld ans = 0;
ld C = 1.0 - powl(1.0 - p, y - 1.0);
ld D = (1.0 - powl(1.0 - p, y - 1.0)) / p;
ld E = (1.0 - powl(p, x - 1.0));
ld F = (1.0 - powl(p, x - 1.0)) / (1.0 - p);
ld f1 = (D * E + F) / (1.0 - C * E);
ld g1 = C * f1 + D;
cout << fixed << setprecision(10) << (ld) (p * f1 + (1.0 - p) * g1 + 1.0) << endl;
}
return 0;
}