bzoj 2969: 矩形粉刷 概率期望
题目:
为了庆祝新的一年到来,小M决定要粉刷一个大木板。大木板实际上是一个W*H的方阵。小M得到了一个神奇的工具,这个工具只需要指定方阵中两个格子,就可以把这两格子为对角的,平行于木板边界的一个子矩形全部刷好。小M乐坏了,于是开始胡乱地使用这个工具。
假设小M每次选的两个格子都是完全随机的(方阵中每个格子被选中的概率是相等的),而且小M使用了K次工具,求木板上被小M粉刷过的格子个数的期望值是多少。
题解:
我们发现我们无法直接进行概率期望dp
因为状态无法记录.
而在这道题中被染色的格子的位置不同也决定着不同的状态.
所以我们考虑转化问题,我们可以分别计算出每个格子k次后被染成黑色的概率.
然后我们求概率之和即为期望.
所以我们把问题转化成了求概率。
因为我们要求的是一个格子k次操作后被染成黑色的概率,而每次操作是染色一个子矩阵.
直接不好计算,所以考虑补集转化.
我们统计每个点在k次操作后仍然没有被染成黑色的概率。然后用1减即可。
至于怎么计算k次操作后没有被染成黑色的概率,我们算出一次染色没有被染到的概率.
再求k次方既可.
一次染色没有被染到的概率瞎XX搞一下就好了.
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
int n,m;
#define sqr(x) ((x)*(x))
inline double calc(int i,int j){
double upside = .0;
upside += sqr(1.0*n*(j-1)) + sqr(1.0*(i-1)*m);
upside += sqr(1.0*(n-i)*m) + sqr(1.0*n*(m-j));
upside -= sqr(1.0*(i-1)*(j-1)) + sqr(1.0*(n-i)*(m-j));
upside -= sqr(1.0*(i-1)*(m-j)) + sqr(1.0*(n-i)*(j-1));
double dnside = sqr(1.0*n*m);
return upside/dnside;
}
inline double qpow(double x,int p){
double ret = 1.0;
for(;p;p>>=1,x=x*x) if(p&1) ret=ret*x;
return ret;
}
int main(){
int T;T = 1;
while(T--){
int k;read(k);read(n);read(m);
double ans = .0;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
ans += 1.0 - qpow(calc(i,j),k);
}
}
printf("%.0f\n",ans);
}
return 0;
}
人就像命运下的蝼蚁,谁也无法操控自己的人生.