bzoj2969 矩形粉刷 概率期望

此题在bzoj是权限题,,,所以放另一个oj的链接

题解:

因为期望线性可加,所以可以对每个方格单独考虑贡献。
每个方格的贡献就为至少被粉刷过一次的概率×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 }
View Code

 

posted @ 2018-12-27 21:45  ww3113306  阅读(191)  评论(0编辑  收藏  举报
知识共享许可协议
本作品采用知识共享署名-非商业性使用-禁止演绎 3.0 未本地化版本许可协议进行许可。