LightOJ - 1284

本文详细解析了一个关于三维空间中开关操作的数学期望问题,通过建立递推公式和概率模型,给出了求解任意次数操作后闭合开关期望数量的方法。
题意

三维空间中任选两点,将两点间的开关按下。进行k次选点,问最终闭合开关的个数的期望。

思路

令f[i]表示选i次点后,该点被按了奇数次的期望,g[i]表示选i次点后,该点被按了偶数次的期望。最终结果就是∑x,y,zf[k]\sum_{{x,y,z}}{f[k]}x,y,zf[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]=pg[i1]+(ip)f[i1]g[i]=pf[i1]+(1p)g[i1]f[i]+g[i]=1
联立后可以解得
f[i]=p+(1−2p)∗f[i−1]f[i] = p+(1-2p)*f[i-1]f[i]=p+(12p)f[i1]
f[1]=pf[1]=pf[1]=p

A=1−2pA=1-2pA=12p
可以推出
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+Af[i1]=p+Ap+A2f[i2]=p+Ap+A2p+A3f[i3]=p(1+A+A2+...+Ai2)+Ai1f[1]=p1A1Ai1+Ai1p.
将A回代后可得
f[i]=12−12∗(1−2p)if[i]=\frac{1}{2}-\frac{1}{2}*(1-2p)^if[i]=2121(12p)i
f[k]即为答案。
p的求法:
p=px∗py∗pzp=p_x*p_y*p_zp=pxpypz
对于每一维:
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=1mm(i1)(i1)+(mi)(mi)


刚开始做的时候,我是对每一维求出该维的概率期望,在将所有维的期望乘起来。即利用
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]=2121(12p)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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值