题意
三维空间中任选两点,将两点间的开关按下。进行k次选点,问最终闭合开关的个数的期望。
思路
令f[i]表示选i次点后,该点被按了奇数次的期望,g[i]表示选i次点后,该点被按了偶数次的期望。最终结果就是∑x,y,zf[k]\sum_{{x,y,z}}{f[k]}x,y,z∑f[k]
f[i]和g[i]的递推式如下:
{f[i]=p∗g[i−1]+(i−p)∗f[i−1]g[i]=p∗f[i−1]+(1−p)∗g[i−1]f[i]+g[i]=1\left\{\begin{aligned}
&f[i] = p*g[i-1]+(i-p)*f[i-1] \\
&g[i] = p*f[i-1]+(1-p)*g[i-1]\\
&f[i]+g[i]=1
\end{aligned}
\right.⎩⎪⎨⎪⎧f[i]=p∗g[i−1]+(i−p)∗f[i−1]g[i]=p∗f[i−1]+(1−p)∗g[i−1]f[i]+g[i]=1
联立后可以解得
f[i]=p+(1−2p)∗f[i−1]f[i] = p+(1-2p)*f[i-1]f[i]=p+(1−2p)∗f[i−1]
f[1]=pf[1]=pf[1]=p
令
A=1−2pA=1-2pA=1−2p
可以推出
f[i]=p+A∗f[i−1]=p+Ap+A2∗f[i−2]=p+Ap+A2p+A3f[i−3]=p∗(1+A+A2+...+Ai−2)+Ai−1f[1]=p∗1−Ai−11−A+Ai−1∗p.\begin{aligned}
f[i]&=p+A*f[i-1]\\
&=p+Ap+A^2*f[i-2]\\
&=p+Ap+A^2p+A^3f[i-3]\\
&=p*(1+A+A^2+...+A^{i-2})+A^{i-1}f[1]\\
&=p*\frac{1-A^{i-1}}{1-A}+A^{i-1}*p
\end{aligned}.f[i]=p+A∗f[i−1]=p+Ap+A2∗f[i−2]=p+Ap+A2p+A3f[i−3]=p∗(1+A+A2+...+Ai−2)+Ai−1f[1]=p∗1−A1−Ai−1+Ai−1∗p.
将A回代后可得
f[i]=12−12∗(1−2p)if[i]=\frac{1}{2}-\frac{1}{2}*(1-2p)^if[i]=21−21∗(1−2p)i
f[k]即为答案。
p的求法:
p=px∗py∗pzp=p_x*p_y*p_zp=px∗py∗pz
对于每一维:
p=1−(i−1)∗(i−1)+(m−i)∗(m−i)m∗mp=1-\frac{(i-1)*(i-1)+(m-i)*(m-i)}{m*m}p=1−m∗m(i−1)∗(i−1)+(m−i)∗(m−i)
刚开始做的时候,我是对每一维求出该维的概率期望,在将所有维的期望乘起来。即利用
E(XYZ)=E(X)E(Y)E(Z)E(XYZ)=E(X)E(Y)E(Z)E(XYZ)=E(X)E(Y)E(Z)
但本题这样求解并不适用。因为期望方程
f[i]=12−12∗(1−2p)if[i]=\frac{1}{2}-\frac{1}{2}*(1-2p)^if[i]=21−21∗(1−2p)i并不满足上式。所以应该用三个for循环去枚举每一个点,求每个点的概率期望。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ld 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;
int x, y, z, k;
inline ld P(int i, int m) {
return (ld) (1.0 - ((m - i) * (m - i) + (i - 1.0) * (i - 1.0)) / (m * m));
}
ld pow_mod(ld a, int b) {
ld ans = 1.0;
while (b) {
if (b & 1)ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
int main() {
__;
int _;
cin >> _;
for (int sce = 1; sce <= _; ++sce) {
cin >> x >> y >> z >> k;
cout << "Case " << sce << ": ";
if (k == 0)cout << 0 << endl;
else {
ld ans = 0.0;
for (int i = 1; i <= x; ++i) {
for (int j = 1; j <= y; ++j) {
for (int t = 1; t <= z; ++t) {
ld p = P(i, x) * P(j, y) * P(t, z);
ans += 0.5 - 0.5 * pow_mod(1.0 - 2.0 * p, k);
}
}
}
cout << fixed << setprecision(10) << ans << endl;
}
}
return 0;
}