【usaco2018dec_silver_T2】convention2 (优先队列)

来源:JZOJ

题目描述

虽然在接机上耽误了挺长时间, F a r m e r J o h n Farmer John 为吃草爱好牛们举行的大会至今为止都非常顺利。大会吸引了世界各地的奶牛。

然而大会的重头戏看起来却给 F a r m e r J o h n Farmer John 带来了一些新的安排上的困扰。他的农场上的一块非常小的牧草地出产一种据某些识货的奶牛说是世界上最美味的品种的草。因此,所有参会的 N N 头奶牛 1 N 1 0 5 (1≤N≤10^5) 都想要品尝一下这种草。由于这块牧草地小到仅能容纳一头奶牛,这很有可能会导致排起长龙。

F a r m e r J o h n Farmer John 知道每头奶牛i计划到达这块特殊的牧草地的时间 a i a_i ,以及当轮到她时,她计划品尝这种草花费的时间 t i t_i 。当奶牛 i i 开始吃草时,她会在离开前花费全部 t i t_i 的时间,此时其他到达的奶牛需要排队等候。如果这块牧草地空出来的时候多头奶牛同时在等候,那么资历最深的奶牛将会是下一头品尝鲜草的奶牛。在这里,恰好在另一头奶牛吃完草离开时到达的奶牛被认为是“在等待的”。类似地,如果当没有奶牛在吃草的时候有多头奶牛同时到达,那么资历最深的奶牛是下一头吃草的奶牛。

请帮助 F J FJ 计算所有奶牛中在队伍里等待的时间( a i a _i 到这头奶牛开始吃草之间的时间)的最大值。

解题思路

  • 这道题要用到优先队列,以资历为第一关键字,因为这样才能保证多头奶牛同时到达,资历最深的奶牛会是下一头吃草的奶牛;
  • 先按到达时间排序,然后用 l a s t last 记录上一头奶牛结束吃草的时间,然后每次找到等待的奶牛,存进堆,这样就可以了;

C o d e Code

#include <bits/stdc++.h>
using namespace std;
int n;
struct node
{
	int t,s,old;
}a[100010];
bool mycmp(node a,node b)
{
	if (a.t!=b.t) return a.t<b.t;
	else return a.old>b.old;
}
int main()
{
	freopen("conven2.in","r",stdin);
	freopen("conven2.out","w",stdout);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%d %d",&a[i].t,&a[i].s);
		a[i].old=n-i+1;  //资历
	}
	sort(a+1,a+n+1,mycmp);  //按到达时间排序
	priority_queue < pair< int , int > > q;
	q.push(make_pair(a[1].old,1));
	int last=a[1].t;
	int ans=-0xfffffff;
	int now=1;
	while (now<=n)
	{
		while (!q.empty())
		{
			int x=q.top().second;
			q.pop();
			ans=max(ans,last-a[x].t);  //更新答案
			while (a[now+1].t<=last+a[x].s && now<n)  //找到等待的牛
			{
				now++;
				q.push(make_pair(a[now].old,now));  //进堆
			}
			last+=a[x].s;
		}
		now++;
		q.push(make_pair(a[now].old,now));
		last=a[now].t;
	}
	cout << ans;
	return 0;
}
发布了34 篇原创文章 · 获赞 39 · 访问量 3824

猜你喜欢

转载自blog.csdn.net/qq_43081996/article/details/104346958
今日推荐