CF912D Fishes 期望 + 贪心

有趣的

由期望的线性性质,全局期望 = 每个格子的期望之和

由于权值一样,我们优先选概率大的点就好了

用一些数据结构来维护就好了

复杂度$O(k \log n)$

#include <set>
#include <map>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
    #define re register
    #define de double
    #define le long double
    #define ri register int
    #define ll long long
    #define sh short
    #define pii pair<int, int>
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define tpr template <typename ra>
    #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
    #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)    
    #define gc getchar
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    int wr[50], rw;
    #define pc(iw) putchar(iw)
    tpr inline void write(ra o, char c = '\n') {
        if(!o) pc('0');
        if(o < 0) o = -o, pc('-');
        while(o) wr[++ rw] = o % 10, o /= 10;
        while(rw) pc(wr[rw --] + '0');
        pc(c);
    }
    tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; }
    tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } 
    tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; }
    tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; }
}
using namespace std;
using namespace remoon;

namespace mod_mod {
    #define mod 1000000007
    inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; }
    inline void dec(int &a, int b) { a -= b; if(a < 0) a += mod; }
    inline int Inc(int a, int b) { return (a + b >= mod) ? a + b - mod : a + b; }
    inline int Dec(int a, int b) { return (a - b < 0) ? a - b + mod : a - b; }
    inline int mul(int a, int b) { return 1ll * a * b % mod; }
}
using namespace mod_mod;

de ans = 0;
int n, m, r, k;
int nx[10] = { 1, -1, 0, 0 };
int ny[10] = { 0, 0, 1, -1 };
struct node {
    int x, y; ll c;
    friend bool operator < (node a, node b)
    { return a.c < b.c; }
};
priority_queue <node> q;
map <pii, int> vis;

inline bool ck(int x, int y) {
    if(x < 1 || x > n) return 0;
    if(y < 1 || y > m) return 0;
    if(vis[mp(x, y)]) return 0;
    else return 1;
}

inline ll solve(int x, int y) {
    ll X = min(min(x, n - x + 1), min(n - r + 1, r));
    ll Y = min(min(y, m - y + 1), min(m - r + 1, r));
    return X * Y;
}

int main() {
    
    n = read(); m = read(); 
    r = read(); k = read();
    
    vis[mp(r, r)] = 1;
    q.push((node){r, r, solve(r, r)});
    
    while(k --) {
        node now = q.top(); q.pop();
        int x = now.x, y = now.y; ans += now.c / (de)(n - r + 1) / (de)(m - r + 1);
        rep(i, 0, 3) {
            int dx = x + nx[i], dy = y + ny[i];
            if(ck(dx, dy)) {
                vis[mp(dx, dy)] = 1;
                q.push((node){dx, dy, solve(dx, dy)});
            }
        }
    }
    
    printf("%.9lf\n", ans);
    return 0;
}

 

posted @ 2018-10-19 08:26  remoon  阅读(163)  评论(0编辑  收藏  举报