【P1717 钓鱼】题解

题目链接

题目

话说发源于小朋友精心设计的游戏被电脑组的童鞋们藐杀之后非常不爽,为了表示安慰和鼓励,VIP999 决定请他吃一次“年年大丰收”,为了表示诚意,他还决定亲自去钓鱼。

但是,因为还要准备 NOIP2013, z老师只给了他 \(H\) 个小时的空余时间,假设有 \(n\) 个鱼塘都在一条水平路边,从左边到右编号为 1, 2, 3 .. n 。

VIP是个很讲究效率的孩子,他希望用这些时间钓到尽量多的鱼。他从湖1出发,向右走,有选择的在一些湖边停留一定的时间钓鱼,最后在某一个湖边结束钓鱼。他测出从第 \(i\) 个湖到 \(i+1\)个湖需要走 \(5 \times t_i\) 分钟的路,还测出在第 \(i\) 个湖边停留,第一个5分钟可以钓到鱼 \(f_i\),以后再每钓5分钟鱼,鱼量减少 \(d_i\)。为了简化问题,他假定没有其他人钓鱼,也不会有其他因素影响他钓到期望数量的鱼。请编程求出能钓最多鱼的数量。

思路

枚举最远去到哪个鱼塘。

然后看排除走路的时间里最多钓的鱼,这里可以用个优先队列维护。

注意是大根堆。

Code

// Problem: P1717 钓鱼
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1717
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
//#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 30
struct node
{
	int x, k; 
	bool operator <(const node &A) const
	{
		return k<A.k; 
	}
}p; 
int n, m, i, j, k; 
int ans, h; 
int f[N], d[N], t[N], s[N]; 
priority_queue<node>q; 

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); h=read()*12; 
	for(i=1; i<=n; ++i) f[i]=read(); 
	for(i=1; i<=n; ++i) d[i]=read(); 
	for(i=2; i<=n; ++i) t[i]=read(); 
	for(i=2; i<=n; ++i) s[i]=s[i-1]+t[i]; 
	for(i=1; i<=n; ++i)
		if(h>=s[i])
		{
			while(!q.empty()) q.pop(); 
			k=0; 
			for(j=1; j<=i; ++j) 
			{
				p.x=j; p.k=f[j]; 
				q.push(p); 
			}
			for(j=1; j<=h-s[i]; ++j)
			{
				p=q.top(); q.pop(); 
				// printf("%d ", p.k); 
				k+=p.k; 
				p.k=max(0, p.k-d[p.x]); 
				q.push(p); 
			}
			ans=max(ans, k); 
			// printf("\n"); 
			// printf("%d\n", k); 
		}
	printf("%d", ans); 
	return 0; 
}

posted @ 2021-12-05 13:59  zhangtingxi  阅读(91)  评论(0编辑  收藏  举报