zoukankan      html  css  js  c++  java
  • Codeforces 912D Fishs ( 贪心 && 概率期望 && 优先队列 )

    题意 : 给出一个 N * M 的网格,然后给你 K 条鱼给你放置,现有规格为 r * r 的渔网,问你如果渔网随意放置去捕捞小鱼的情况下,捕到的最大期望值是多少?

    分析 : 

    有一个很直观的想法就是如果将鱼放在越靠近中间的位置,其被捕捞的可能性越大

    事实也的确如此,鱼的位置越靠近边缘则能覆盖到它的渔网安放位置就越少

    那么这就有了一个贪心的算法

    将第一条鱼放在最中间的位置算出被捕捉的概率

    被捕捉的概率 = 能覆盖到当前小鱼位置的渔网个数 / 整个网格的全部安放渔网的方法数

    然后从中间这个点开始向四周扩散,然后再找出概率最大的来进行扩张

    因为概率越大说明其位置越靠近中间,所以首选概率最大的点进行扩张

    这很像 BFS 的过程,所以我们可以使用一个优先队列来维护扩散出来的最大概率

    然后选出前 K 个即可

    对于每一个点能被多少个渔网放置方法覆盖,有个简便的方法

    我们先分别算出横纵上的每一个点被覆盖的方法数即 (1~N, 1) 和 (1, 1~M)

    然后对于中间的某个点,只要将刚刚算出来的结果进行相乘即可例如 (N, M) = (N, 1) * (1, M)

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int maxn = 1e5 + 10;
    const int dr[] = {1,  -1,   0,  0};
    const int dc[] = {0,   0,  -1,  1};
    struct NODE{
        double P;
        int row, col;
        NODE(){};
        NODE(int r, int c, double p):row(r),col(c),P(p){};
        bool operator < (const NODE &rhs) const{
            return this->P < rhs.P;
        };
    };
    
    set<pair<int, int> > s;///由于N*M太大了,所以用set进行判重
    priority_queue<NODE> que;
    int R[maxn], C[maxn];
    int n, m, r, k;
    
    bool bound(int row, int col)///判断是否越界,越界返回 true
    { return (row<1 || col<1 || row>n || col>m); }
    
    int add[maxn];
    inline void Calculate_R_Array(int len, int r)///计算纵轴上每个点被覆盖的方案数
    {
        for(int i=1; i<=len-r+1; i++)
            add[i]++, add[i+r]--;
        int sum = 0;
        for(int i=1; i<=len; i++)
            sum += add[i],
            R[i] = sum;
    }
    
    inline void Calculate_C_Array(int len, int r)///计算横轴
    {
        for(int i=1; i<=len-r+1; i++)
            add[i]++, add[i+r]--;
        int sum = 0;
        for(int i=1; i<=len; i++)
            sum += add[i],
            C[i] = sum;
    }
    
    int main(void)
    {
        while(~scanf("%d %d %d %d", &n, &m, &r, &k)){
            s.clear(); while(!que.empty()) que.pop();
            LL tot = (LL)(n-r+1)*(LL)(m-r+1);///注意使用 long long 存储
    
            memset(add, 0, sizeof(add));
            Calculate_R_Array(n, r);
            memset(add, 0, sizeof(add));
            Calculate_C_Array(m, r);
    
            s.insert(make_pair(n/2+1, m/2+1));
            que.push(NODE(n/2+1, m/2+1, (double)(C[m/2+1]*R[n/2+1])/(double)tot));
            double ans = 0;
            while(k--){
                NODE T = que.top();
                que.pop();
                ans += T.P;
                for(int i=0; i<4; i++){///向四个点扩散
                    int newr = T.row + dr[i];
                    int newc = T.col + dc[i];
                    if(bound(newr, newc)) continue;
                    if(!s.count(make_pair(newr, newc))){
                        s.insert(make_pair(newr, newc));
                        que.push(NODE(newr, newc, (double)(C[newc]*R[newr])/(double)tot));
                    }
                }
            }
            printf("%.9f
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ligerui_ligerTree_007_ligerTree动态加载节点
    ligerui_ligerTree_006_ligerui事件支持
    ligerui_ligerTree_005_动态增加“树”节点
    ligerui_ligerTree_004_对"ligerTree"节点操作
    ligerui_ligerTree_003_配置url参数,加载“树”
    ligerui_ligerTree_002_利用JavaScript代码配置ligerTree节点
    ligerui_ligerTree_001_第一个“树”效果
    ligerui_实际项目_003:form中添加数据,表格(grid)里面显示,最后将表格(grid)里的数据提交到servlet
    ligerui+json_002_Grid用法、属性总结
    ligerui+json_001_实现表格(grid)的后台数据显示、分页
  • 原文地址:https://www.cnblogs.com/qwertiLH/p/8432803.html
Copyright © 2011-2022 走看看