zoukankan      html  css  js  c++  java
  • CodeForces 912d fishes(优先队列+期望)

    While Grisha was celebrating New Year with Ded Moroz, Misha gifted Sasha a small rectangular pond of size n × m, divided into cells of size 1 × 1, inhabited by tiny evil fishes (no more than one fish per cell, otherwise they'll strife!).

    The gift bundle also includes a square scoop of size r × r, designed for fishing. If the lower-left corner of the scoop-net is located at cell(x, y), all fishes inside the square (x, y)...(x + r - 1, y + r - 1) get caught. Note that the scoop-net should lie completely inside the pond when used.

    Unfortunately, Sasha is not that skilled in fishing and hence throws the scoop randomly. In order to not frustrate Sasha, Misha decided to release k fishes into the empty pond in such a way that the expected value of the number of caught fishes is as high as possible. Help Misha! In other words, put k fishes in the pond into distinct cells in such a way that when the scoop-net is placed into a random position among (n - r + 1)·(m - r + 1) possible positions, the average number of caught fishes is as high as possible.

    Input

    The only line contains four integers n, m, r, k (1 ≤ n, m ≤ 105, 1 ≤ r ≤ min(n, m), 1 ≤ k ≤ min(n·m, 105)).

    Output

    Print a single number — the maximum possible expected number of caught fishes.

    You answer is considered correct, is its absolute or relative error does not exceed 10 - 9. Namely, let your answer be a, and the jury's answer be b. Your answer is considered correct, if .

    Examples
    input
    Copy
    3 3 2 3
    output
    Copy
    2.0000000000
    input
    Copy
    12 17 9 40
    output
    Copy
    32.8333333333
    Note

    In the first example you can put the fishes in cells (2, 1), (2, 2), (2, 3). In this case, for any of four possible positions of the scoop-net (highlighted with light green), the number of fishes inside is equal to two, and so is the expected value.

    题意:给出一个n*m的渔池,再给你一张r*r的网,往池子里放k条鱼,每个格子只能放一条,求随机撒网捞到鱼的最大期望。

    题解:一开始准备用纯数学公式法做,复杂度为sqrt(k),但是有不少细节不好处理,索性写暴力了。

    首先先转换一下思路,所有渔网网到的鱼之和等于每条鱼被几张网网到的和,然后期望就是所有鱼的期望相加。

    很容易可以证明,(r,r)位置上的期望一定是最大的之一(可以尝试用反证法自己证一下)

    我们把这个位置扔进优先队列,之后每次从优先队列里取出期望最大的数给答案加上,再把周围四个中没有越界没有被访问过的塞进去,一共取出k次

    复杂度是(klogk)还是符合条件的。

    代码如下:

    #include<map>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct node
    {
        int x,y;
        double val;
        friend bool operator <(const node &a, const node &b)
        {
            return a.val<b.val;
        }
    };
    
    int n,m,r,k;
    double ans=0.0;
    priority_queue<node> q;
    map< pair<int,int> ,int > mp;
    
    int check(int x,int y)
    {
        return x>=1&&x<=n&&y>=1&&y<=m&&(mp.count(make_pair(x,y))==0);
    }
    
    double get(int x,int y)
    {
        double xx=min(min(1.00*x,n-x+1.00),min(n-r*1.00+1,1.00*r));
        double yy=min(min(1.00*y,m-y+1.00),min(m-r*1.00+1,1.00*r));
        return xx*yy/1.00/(n-r+1)/(m-r+1);
    }
    
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&r,&k);
        q.push({r,r,get(r,r)});
        mp[make_pair(r,r)]=1;
        while(k--)
        {
            node now=q.top();
            int nx=now.x,ny=now.y;
            double nval=now.val;
            ans+=nval;
            q.pop();
            if(check(nx+1,ny))
            {
                mp[make_pair(nx+1,ny)];
                q.push({nx+1,ny,get(nx+1,ny)});
            }
            if(check(nx-1,ny))
            {
                mp[make_pair(nx-1,ny)];
                q.push({nx-1,ny,get(nx-1,ny)});
            }
            if(check(nx,ny+1))
            {
                mp[make_pair(nx,ny+1)];
                q.push({nx,ny+1,get(nx,ny+1)});
            }
            if(check(nx,ny-1))
            {
                mp[make_pair(nx,ny-1)];
                q.push({nx,ny-1,get(nx,ny-1)});
            }
        }
        printf("%.12lf
    ",ans);
    }
  • 相关阅读:
    支付宝 微信支付 移动支付 网站支付 开发
    2017 开源中国评比的前100个优秀开源项目
    解决error: Your local changes to the following files would be overwritten by merge
    Spring-JDBC配置
    server library[unbound] 服务未绑定解决办法
    MyEclipse安装EGit插件方法
    使用GitHub和Eclipse进行javaEE开发步骤
    Spring-AOP
    SQL-字符串连接聚合函数
    Spring-注入外部值
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8835157.html
Copyright © 2011-2022 走看看