LightOJ - 1284

题意

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

思路

令f[i]表示选i次点后,该点被按了奇数次的期望,g[i]表示选i次点后,该点被按了偶数次的期望。最终结果就是 ∑ x , y , z f [ 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 − 2 p ) ∗ f [ i − 1 ] f[i] = p+(1-2p)*f[i-1] f[i]=p+(12p)f[i1]
f [ 1 ] = p f[1]=p f[1]=p

A = 1 − 2 p A=1-2p A=12p
可以推出
f [ i ] = p + A ∗ f [ i − 1 ] = p + A p + A 2 ∗ f [ i − 2 ] = p + A p + A 2 p + A 3 f [ i − 3 ] = p ∗ ( 1 + A + A 2 + . . . + A i − 2 ) + A i − 1 f [ 1 ] = p ∗ 1 − A i − 1 1 − A + A i − 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 ] = 1 2 − 1 2 ∗ ( 1 − 2 p ) i f[i]=\frac{1}{2}-\frac{1}{2}*(1-2p)^i f[i]=2121(12p)i
f[k]即为答案。
p的求法:
p = p x ∗ p y ∗ p z p=p_x*p_y*p_z p=pxpypz
对于每一维:
p = 1 − ( i − 1 ) ∗ ( i − 1 ) + ( m − i ) ∗ ( m − i ) m ∗ m p=1-\frac{(i-1)*(i-1)+(m-i)*(m-i)}{m*m} p=1mm(i1)(i1)+(mi)(mi)


刚开始做的时候,我是对每一维求出该维的概率期望,在将所有维的期望乘起来。即利用
E ( X Y Z ) = E ( X ) E ( Y ) E ( Z ) E(XYZ)=E(X)E(Y)E(Z) E(XYZ)=E(X)E(Y)E(Z)
但本题这样求解并不适用。因为期望方程
f [ i ] = 1 2 − 1 2 ∗ ( 1 − 2 p ) i f[i]=\frac{1}{2}-\frac{1}{2}*(1-2p)^i f[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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值