• [CF912D]Fishes


    给一个 (n imes m) 的网格,让你在里面放刚好 (k) 条鱼(位置不能相同),随机用一个 (r imes r) 的网覆盖(共 ((n - r + 1)(m - r + 1)) 种方法),最大化覆盖到鱼的数量的期望。


    由期望的线性性,答案是每个格子被访问到的期望。我们不妨先将答案乘上 ((n - r + 1)(m - r + 1)) 来考虑。

    我们想象有一个滑动的窗口,它只在 (x) 轴滑和只在 (y) 轴滑的过程——实际上两维是独立的。

    对于一维,记长度为 (n),考虑左端点可行位置,得到一个数组 (A_i = min(i, n - r + 1) - max(1, i - r + 1) + 1)

    那么,在每个位置的贡献就是 (x) 轴数组 (A)(y) 轴数组 (B) 的笛卡尔积 (M_{i,j} = A_i B_j)

    (A)(B) 显然是单峰的(当然也是对称的),所以笛卡尔积之后也是单峰的。

    daklqw@daklqw:~/workspace/code$ ./fish
    12 17 9
    1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
    2 4 6 8 10 12 14 16 18 16 14 12 10 8 6 4 2
    3 6 9 12 15 18 21 24 27 24 21 18 15 12 9 6 3
    4 8 12 16 20 24 28 32 36 32 28 24 20 16 12 8 4
    4 8 12 16 20 24 28 32 36 32 28 24 20 16 12 8 4
    4 8 12 16 20 24 28 32 36 32 28 24 20 16 12 8 4
    4 8 12 16 20 24 28 32 36 32 28 24 20 16 12 8 4
    4 8 12 16 20 24 28 32 36 32 28 24 20 16 12 8 4
    4 8 12 16 20 24 28 32 36 32 28 24 20 16 12 8 4
    3 6 9 12 15 18 21 24 27 24 21 18 15 12 9 6 3
    2 4 6 8 10 12 14 16 18 16 14 12 10 8 6 4 2
    1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
    daklqw@daklqw:~/workspace/code$ ./fish
    3 3 2
    1 2 1
    2 4 2
    1 2 1
    

    所以我们直接从最中间开始贪心,用 BFS 和 优先队列找到前 k 大的位置即可。

    下面是远古时期的代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <set>
    using namespace std;
    int n,m,r,k;
    const int ways[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    double ans,tot;
    struct element{
    	int x,y;long long val;
    	inline bool operator<(const element & b)const{
    		return val<b.val;
    	}
    };
    inline long long getv(int x,int y){
    	int t1=max(x-r+1,1),t2=max(y-r+1,1),
    		t3=min(x+r-1,n)-r+1,t4=min(y+r-1,m)-r+1;
    	if(t3<t1|t4<t2)return -1;
    	return 1LL*(t3-t1+1)*(t4-t2+1);
    }
    priority_queue<element>q;
    set<pair<int,int> >s;
    int main(){
    	scanf("%d%d%d%d",&n,&m,&r,&k);
    	if(n>m)swap(n,m);
    	q.push((element){n+1>>1,m+1>>1,getv(n+1>>1,m+1>>1)});
    	s.insert(make_pair(n+1>>1,m+1>>1));
    	for(int i=1;i<=k;++i){
    		element t=q.top();q.pop();
    		tot+=t.val;
    		for(register int j=0;j<4;++j){
    			int tx=t.x+ways[j][0],
    			ty=t.y+ways[j][1];
    			if(tx<1||ty<1||tx>n||ty>m)continue;
    			if(s.find(make_pair(tx,ty))!=s.end())continue;
    			q.push((element){tx,ty,getv(tx,ty)});
    			s.insert(make_pair(tx,ty));
    		}
    	}
    	printf("%.10lf
    ",tot/double(n-r+1)/double(m-r+1));
    	return 0;
    }
    
  • 相关阅读:
    SQLServer中的死锁的介绍
    T-SQL基础--TOP
    jQuery 与js判断是否单选复选选中
    动态替换iframe的src及动态改变iframe的高度
    ztree-持续更新中
    java发送http连接
    nginx配置文件详解
    eclipse Mars4.5.2安装fatjar
    java Scanner类注意事项
    纯java+maven+sqlserver使用mybatis
  • 原文地址:https://www.cnblogs.com/daklqw/p/8231284.html
Copyright © 2020-2023  润新知