LightOJ 1284 Lights inside 3D Grid (期望)

题意:一个X * Y * Z的立方体,每个灯泡一开始都是关闭的,有m次反转操作,每次操作随机选择两个点,将两个点之间的灯泡全部反转,求灯泡亮的期望个数。

题解:期望
考虑每个灯泡的贡献,每个灯泡亮着的概率就是单个灯泡的期望,全部累加就是结果。
对于点C(x,y,z)只有当被选中的2个点A(x1,y1,z1),B(x2,y2,z2),满足x1<=x<=x2且y1<=y<=y2且z1<=z<=z2时,该点的状态才会改变,我们现求单个被选择(改变)的概率p。
先考虑一维,组合表示排列:p = ACB = 1 - ABC - CAB
三维就是三个概率相乘。

接下来考虑已经进行x次选择。 f ( x ) f(x) f(x)表示被选择奇数次概率,即最后灯亮, g ( x ) g(x) g(x)表示偶数次概率,即最后灯灭。
f ( x ) + g ( x ) = 1 f(x)+g(x) = 1 f(x)+g(x)=1
f ( x ) = f ( x − 1 ) ∗ ( 1 − p ) + g ( x − 1 ) ∗ p f(x) = f(x - 1) * (1 - p) + g(x - 1) * p f(x)=f(x1)(1p)+g(x1)p
两式联立化简可以得到 f ( x ) − 1 / 2 = ( 1 − 2 ∗ p ) ( f ( x − 1 ) − 1 / 2 ) f(x)-1/2=(1-2*p)(f(x-1)-1/2) f(x)1/2=(12p)(f(x1)1/2) f ( 1 ) = p f(1) = p f(1)=p,等比公式可以化简得到 f ( m ) = ( 1 − ( 1 − 2 ∗ p ) m ) / 2 f(m)=(1-(1-2*p) ^ m)/2 f(m)=(1(12p)m)/2,然后每个点累加即可。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
int t, x, y, z, m;
double cal(int x, int n) {
	return 1 - 1.0 * (x - 1) * (x - 1) / n / n - 1.0 * (n - x) * (n - x) / n / n;
}
int main() {
	scanf("%d", &t);
	int cas = 0;
	while (t--) {
		scanf("%d%d%d%d", &x, &y, &z, &m);
		double ans = 0;
		for (int i = 1; i <= x; i++) {
			for (int j = 1; j <= y; j++) {
				for (int k = 1; k <= z; k++) {
					double p = cal(i, x) * cal(j, y) * cal(k, z);
					ans += 1.0 * (1 - pow(1 - 2 * p, m)) / 2;
				}
			}
		}
		printf("Case %d: %f\n", ++cas, ans);
	}
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值