• 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);
    }
  • 相关阅读:
    NetBeans 时事通讯(刊号 # 52 Apr 15, 2009)
    Linux 3.8.1 电源管理之OMAP Clock Domain分析
    基础架构部_超大规模数据平台架构师(上海)
    C Programming/Pointers and arrays Wikibooks, open books for an open world
    这个帖子介绍了关于structure和及struct arrary 作为参数 传递
    thinking point
    velocity
    枫芸志 » 【C】int与size_t的区别
    Pointers and Text Strings
    comp.lang.c Frequently Asked Questions 非常 好
  • 原文地址:https://www.cnblogs.com/stxy-ferryman/p/8835157.html
Copyright © 2020-2023  润新知