钓鱼

白昼怎懂夜的黑 提交于 2019-12-02 16:21:51

https://loj.ac/problem/10009

题目描述

  有n个鱼塘,每个鱼塘有两个量,一个是初始每时刻能钓到的鱼的数量,还有一个是每钓一段时间每时刻能钓到鱼的数量的减少量。两两鱼塘之间有一定的距离,求在t时间最多钓到多少鱼

思路

  这题的做法比较多,主流以贪心和\(dp\)为主,这里就讲贪心。首先这个\(5\)分钟可以直接看做一个刻度,先与处理掉。在考虑每个鱼塘的情况,由于往返两个鱼塘的耗时难以确定,但我们假设已知最优解,那么最优解一定不会往返走,也就是说,一定是在一个鱼塘钓到一定数量的鱼在离开。所以我们只需算一次跨越鱼塘的花费,之后就可以“\(0\)”的往返了。有了这个贪心策略,我们就可以循环\(i\)\(1\sim n\),表示在\(1\sim i\)个鱼塘中最多钓到的个数,在维护一个优先队列表示目前一个时刻最多钓到的鱼的个数,去那里钓鱼并将新的数目加入队列。

代码

#include <bits/stdc++.h>
using namespace std;
struct aa
{
    int s,t;
    bool operator <(const aa &x)const
    {
        return s<x.s;
    }
}a[110];
int l[110];
priority_queue<aa>q;
int main() 
{
    int n,h;
    scanf("%d%d",&n,&h);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].s);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i].t);
    for(int i=2;i<=n;i++)
        scanf("%d",&l[i]);
    h=h*12;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        h-=l[i];
        int m=h,sum=0;
        for(int j=1;j<=i;j++)
            q.push(a[j]);
        while(m>0)
        {
            aa p=q.top();q.pop();
            if(p.s<=0)break ;
            sum+=p.s;
            p.s-=p.t;
            q.push(p);
            m--;
        }
        ans=max(ans,sum);
    }
    printf("%d",ans);
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!