2016 UESTC Training for Data Structures J - 郭大侠与Rabi-Ribi CDOJ 1334 优先队列

J - 郭大侠与Rabi-Ribi

就是有N只兔子,每只兔子会存在a[i]秒,价值为v[i],然后每秒只能取一只兔子,问能取的兔子总价值的最大值是多少

用一个堆/优先队列维护就好了

首先我们先把兔子按存在时间升序排序,然后第一秒的时候,我们取第一只兔子,并放进堆中,堆是小根堆,按兔子的价值排序的,堆顶为价值最小的兔子

然后我们就一秒一秒的取,如果下一只兔子的存在时间>=当前时间,那就直接把下一只兔子放进来,然后如果下一只兔子的存在时间<当前时间,然后如果这只兔子比堆顶的兔子的价值大时,说明我们当时应该不取堆顶的兔子而取这一只兔子,于是就把堆顶的给pop,把这只兔子push就可以啦,同时维护一下总价值

然后把N只兔子遍历一遍,答案也就得到了

复杂度nlogn


代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define maxn 100005
struct Node
{
	ll a, v;
	bool operator <(Node x)const
	{
		return v > x.v;
	}
}rabbit[maxn];
bool cmp(Node x, Node y)
{
	return x.a < y.a;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	int N;
	scanf("%d", &N);
	for (int i = 0; i < N; ++i)
		scanf("%lld", &rabbit[i].a);
	for (int i = 0; i < N; ++i)
		scanf("%lld", &rabbit[i].v);
	sort(rabbit, rabbit + N, cmp);
	priority_queue<Node> Q;
	ll time = 0, ans = 0;
	Q.push(rabbit[0]);
	++time, ans += rabbit[0].v;
	for (int i = 1; i < N; ++i)
	{
		//printf("%lld\n", Q.top().v);
		if (rabbit[i].a <= time&&rabbit[i].v>Q.top().v)
		{
			ans -= Q.top().v;
			ans += rabbit[i].v;
			Q.pop();
			Q.push(rabbit[i]);
			//++time;
		}
		else if (rabbit[i].a>time)
		{
			Q.push(rabbit[i]);
			++time;
			ans += rabbit[i].v;
		}
	}
	printf("%lld\n", ans);
	//system("pause");
	//while (1);
	return 0;
}

你可能感兴趣的:(2016 UESTC Training for Data Structures J - 郭大侠与Rabi-Ribi CDOJ 1334 优先队列)