LightOJ 1284 Lights inside 3D Grid 概率/期望

Lights inside 3D Grid LightOJ - 1284

给一个三维格子,每个维度的大小为 X,Y,ZX,Y,Z,每个位置有一盏灯,刚开始的时候每个灯都关着,进行 KK 次操作:

(1)随机选一个格子 AA
(2)随机再选一个格子 BB
(3)改变由 A,BA,B 包围起来的方体的灯的状态(开\to关,关\to开)

计算 KK 次操作后,开灯数的期望。

对于每一个点 (x,y,z)(x,y,z),设选中的格点分别为 (x1,y1,z1),(x2,y2,z2)(x_1,y_1,z_1),(x_2,y_2,z_2),只有当 x1xx2x_1\le x\le x_2y1yy2y_1\le y\le y_2z1zz2z_1\le z\le z_2 时,点的状态才会改变,设点分别在这三个区间内的概率为 px,py,pzp_x,p_y,p_z,则 px=1p_x=1- 不在[x1,x2][x_1,x_2] 区间内的概率,而不在 [x1,x2][x_1,x_2] 区间内的概率 == 随机的两个边界点都在 xx 的同一侧的概率,因此有:

px=1(x1X)2(XxX)2 p_x=1-(\frac{x-1}{X})^2-(\frac{X-x}{X})^2

其中 XXxx 所在维度的大小。

pp(x,y,z)(x,y,z)A,BA,B 之间的概率,则

p=pxpypz p=p_xp_yp_z

总共要进行 KK 轮,那么每一轮使得 (x,y,z)(x,y,z)A,BA,B 之间的概率都是 pp,当该点总共在区间内的次数是奇数次时,这个灯才是亮着的状态,设 f(i)f(i)ii 轮之后,在区间内的次数是奇数次的概率,g(i)g(i) 为相应偶数次的概率,则:

f(i)=pg(i1)+(1p)f(i1)g(i)=pf(i1)+(1p)g(i1)f(i)+g(i)=1 \begin{aligned} f(i)&=pg(i-1)+(1-p)f(i-1)\\ g(i)&=pf(i-1)+(1-p)g(i-1)\\ f(i)+g(i)&=1 \end{aligned}

解上述等式组,得:

f(i)=p(1f(i1))+(1p)f(i1)f(i)=p+(12p)f(i1)f(i)+a=(12p)(f(i1)+a)f(i)=2pa+(12p)f(i1)a=12f(i)12=(12p)(f(i1)12)f(i)12=(12p)i1(f(1)12)=(12p)i2f(i)=1(12p)i2 \begin{aligned} f(i)&=p(1-f(i-1))+(1-p)f(i-1)\\ f(i)&=p+(1-2p)f(i-1)\\ f(i)+a&=(1-2p)(f(i-1)+a)\\ f(i)&=-2pa+(1-2p)f(i-1)\\ a&=-\frac{1}{2}\\ f(i)-\frac{1}{2}&=(1-2p)(f(i-1)-\frac{1}{2})\\ f(i)-\frac{1}{2}&=(1-2p)^{i-1}(f(1)-\frac{1}{2})=-\frac{(1-2p)^i}{2}\\ f(i)&=\frac{1-(1-2p)^i}{2} \end{aligned}

因此 f(K)=1(12p)K2f(K)=\dfrac{1-(1-2p)^K}{2}

代码如下:

#include<iostream>
#include<cstdio>
//#define WINE
#define P(x,X) (1-(1.0*(x-1)*(x-1)+(X-x)*(X-x))/(X*X))
using namespace std;
int T,iCase,X,Y,Z,K;
double res,p;
double pow(double x,int p){
    double base=x,res=1;
    while(p){
        if(p&1)res*=base;
        base*=base;
        p>>=1;
    }
    return res;
}
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d%d",&X,&Y,&Z,&K);
        res=0;
        for(int x=1;x<=X;x++)
            for(int y=1;y<=Y;y++)
                for(int z=1;z<=Z;z++){
                    p=P(x,X)*P(y,Y)*P(z,Z);
                    res+=(1-pow(1-2*p,K))/2;
                }
        printf("Case %d: %.8lf\n",++iCase,res);
    }
    return 0;
}

在这里插入图片描述

posted @ 2020-03-26 08:11  winechord  阅读(84)  评论(0编辑  收藏  举报