CF912D Fishes

题目链接:http://codeforces.com/contest/912/problem/D

题目大意:

  在一个(n imes m)的网格中放鱼(每个网格只能放一条鱼),用一个(r imes r)的网随机地捕一次鱼,问如何放置鱼能使得捕到的鱼的期望值最大,求最大值。

知识点:  优先队列、概率与期望

解题思路:

  要使捕到鱼的期望值最大,就应该往最有可能被渔网捞到的格子里放鱼。

  (P(某个格子被捞到)= N_1(渔网能捞到这个格子的放置方案数)/N_2(渔网总放置方案数),)

  (N(渔网总放置方案数) = (n-r+1) imes(m-r+1))

  而要求(N_1),我们可以先算出最左边一列和最上边一行的各个格子对应的(N_1),(N_1(x,y) = N_1(x,0) imes N_1(0,y))。于是我们可以从最中间的格子开始(直觉告诉我们:最中间的格子总是最有可能被捞到),用一个优先队列维护,每次都往上下左右四个方向拓展,找出前 (k) 个最有可能被捞到的位置所对应的期望值,加起来所得到的总和即为答案。

AC代码:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn = 1e5+5;
 5 const int cx[4]={1,-1,0,0},cy[4]={0,0,1,-1};
 6 
 7 int line[maxn],col[maxn];
 8 struct node{
 9     int x,y;
10     double z;
11     friend bool operator <(const node &a,const node &b){
12         return a.z<b.z;
13     }
14 };
15 map<pair<int,int>,int> vis;
16 priority_queue<node> q;
17 
18 int main(){
19     int n,m,r,k;
20     scanf("%d%d%d%d",&n,&m,&r,&k);
21     for(int i=1;i<=(n+1)/2;i++){
22         if(i<=n-r+1)    line[i]=min(i,r);
23         else    line[i]=line[i-1];
24     }
25     for(int i=n,j=1;i>(n+1)/2;i--,j++)
26         line[i]=line[j];
27 
28     for(int i=1;i<=(m+1)/2;i++){
29         if(i<=m-r+1)    col[i]=min(i,r);
30         else    col[i]=col[i-1];
31     }
32     for(int i=m,j=1;i>(m+1)/2;i--,j++)
33         col[i]=col[j];
34 
35     double tot=(double)(n-r+1)*(m-r+1),ans=0.0;
36     node now,next;
37     now.x=(n+1)/2,now.y=(m+1)/2;
38     now.z=(double)line[now.x]*col[now.y]/tot;
39     q.push(now);
40     vis[make_pair(now.x,now.y)]=1;
41     while(k--){
42         now=q.top();
43         q.pop();
44         ans+=now.z;
45         for(int i=0;i<4;i++){
46             int nx=now.x+cx[i],ny=now.y+cy[i];
47             if(nx>0&&nx<=n&&ny>0&&ny<=m&&!vis[make_pair(nx,ny)]){
48                 next.x=nx,next.y=ny,next.z=(double)line[next.x]*col[next.y]/tot;
49                 q.push(next);
50                 vis[make_pair(nx,ny)]=1;
51             }
52         }
53     }
54     printf("%.10lf
",ans);
55 
56     return 0;
57 }
“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/8319001.html