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; }