codeforces 912D 期望计算

本文介绍了一种解决特定问题的高效算法:如何在一个n*m的鱼塘中放置k条鱼,以使通过选取r*r矩阵来获取的期望得分最大。采用bfs搜索与优先队列的方法,计算每个位置的期望得分,并选取最高的k个得分位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题意:在一个n*m的鱼塘里面放置k条鱼,每次可以选定一个r*r的矩阵并获得矩阵内鱼的数量的分数。请问该如何在鱼塘里面放置鱼,使得最后的期望得分最大。

思路:直接通过枚举放置鱼的位置计算期望得分明显非常非常不现实,于是我们换一种计算思路我们去计算各点放置鱼之后可以得到的期望得分,然后取前k大的位置得分即可得到题目所说的答案。有一个明显的结论(r,r)这点的期望得分一定期望得分最高的点之一,于是解决方案就出来了。以(r,r)为起点向四个方向进行bfs,以map代替vis[][]标记并用priority_queue维护数据,取前k大期望得分点进行累加。

C++代码:

#include<bits/stdc++.h>
using namespace std;

int  n,m,r,k;
double ans=0;
int dx[4] = {-1,1,0,0};
int dy[4] = {0,0,-1,1};

struct node
{
    int  x,y;
    double z;
    friend bool operator<( const node&a , const node&b )
    {
        return a.z<b.z;
    }
};

priority_queue<node>PQ;
map<pair<int,int>,int>mp;

double fun( int x , int y ) //期望得分计算函数
{
    double x1 = min( 1.0*x , 1.0*n-x+1 ); x1 = min( x1 , 1.0*n-r+1 ); x1 = min( x1 , r*1.0 );
    double y1 = min( 1.0*y , 1.0*m-y+1 ); y1 = min( y1 , 1.0*m-r+1 ); y1 = min( y1 , r*1.0 );
    return x1*y1/(n-r+1)/(m-r+1);
}

bool ok( int x , int y )
{
    return x>=1&&x<=n&&y>=1&&y<=m&&!mp.count(make_pair(x,y));
}

int main()
{
    scanf ( "%d%d%d%d" , &n , &m , &r , &k );
    node  p;
    p.x = r;
    p.y = r;
    p.z = fun( r , r );
    mp[make_pair(r,r)] = 1;
    PQ.push(p);
    while( k-- )
    {
        p = PQ.top();
        PQ.pop();
        int x = p.x;
        int y = p.y;
        ans  += p.z;
        for ( int i=0 ; i<4 ; i++ )
        {
            int tx = x+dx[i];
            int ty = y+dy[i];
            if ( ok( tx , ty ) )
            {
                mp[make_pair(tx,ty)] = 1;
                p.x = tx;
                p.y = ty;
                p.z = fun( p.x , p.y );
                PQ.push(p);
            }
        }
    }
    printf ( "%.10lf\n" , ans );
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值