bzoj2969 矩形粉刷 概率期望
题解:
因为期望线性可加,所以可以对每个方格单独考虑贡献。
每个方格的贡献就为至少被粉刷过一次的概率×1(每个格子的最大贡献就是1...)
每个方格至少被粉刷过一次的概率=1 - 一次都没被粉刷过的概率
因为每次选择都不互相影响,因此我们实际上只需要计算对于每一次选择而言,每个方格不被粉刷的概率,设这个概率为t,那么k次都没被粉刷过的概率就为$t^{k}$.
对于一个方格而言,如果它在一次选择中不被粉刷,那么就意味这这次选中的2个点都在它的同一个方向(左右上下)。但是这样算会把一些区域的方案计算2次(例如左边和上面这2个矩形的重叠部分内的方案就被计算了2次,因此再减去这些重叠部分的贡献即可)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define R register int 4 #define RL register long long 5 #define h(x) (1.0 * x * x)//这里要乘1.0转double 6 #define LL long long 7 8 LL n, m, k; double ans; 9 10 void pre(){ 11 scanf("%lld%lld%lld", &k, &n, &m); 12 } 13 14 double qpow(double x, int have) 15 { 16 double rnt = 1; 17 while(have) 18 { 19 if(have & 1) rnt *= x; 20 x *= x, have >>= 1; 21 } 22 return rnt; 23 } 24 25 void work() 26 { 27 double all = h(n * m); 28 for(R i = 1; i <= n; i ++) 29 { 30 for(R j = 1; j <= m; j ++) 31 { 32 double t = h((i - 1) * m) + h((n - i) * m) + h((j - 1) * n) + h((m - j) * n); 33 t -= h((i - 1) * (j - 1)) + h((i - 1) * (m - j)) + h((n - i) * (j - 1)) + h((n - i) * (m - j)); 34 //printf("%lf\n", t); 35 ans += 1 - qpow(t / all, k); 36 } 37 } 38 if(ans - (int) ans >= 0.499999) printf("%lld\n", ((LL)ans) + 1); 39 else printf("%lld\n", (LL) ans); 40 } 41 42 int main() 43 { 44 freopen("in.in", "r", stdin); 45 pre(); 46 work(); 47 fclose(stdin); 48 return 0; 49 }