【堆】【贪心】Leopard学霸

D e s c r i p t i o n Description

马上假期就要到了,THU的神犇Leopard假期里都不忘学霸,现在有好多门功课,每门功课都耗费他1单位时间来学习。
他的假期从0时刻开始,有1000000000个单位时间(囧rz)。在任意时刻,他都可以任意一门功课(编号1~n)来学习。
因为他在每个单位时间只能学习一门功课,而每门功课又都有一个截止日期,所以他很难完成所有n门功课。
对于第i门功课,有一个截止时间Di,若他能学完这门功课,他能够获得知识Pi。
在给定的功课和截止时间下,Leopard能够获得的知识最多为多少呢?

I n p u t Input

第一行,一个整数n,表示功课的数目
接下来n行,每行两个整数,Di和Pi

O u t p u t Output

输出一行一个整数,表示最多学得的知识数

S a m p l e Sample I n p u t Input

3
2 10
1 5
1 7

S a m p l e Sample O u t p u t Output

17

H i n t Hint

【样例说明】	
第一个单位时间学习第3个功课(1,7)
然后在第二个单位时间学习							
第1个功课(2,10)

T r a i n Train o f of T h o u g h t Thought

把每一项活动按结束时间排序, 然后一个个枚举活动,判断前面的时间是否可以塞入一个活动,有的话就塞,否则就看是否能与小根堆堆顶(前面所用时间中的单个价值)比较,看是否要交换

C o d e Code

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<queue>

using namespace std;

bool b, finish[100005];
int n;
long long time, ans;

long long maxx (long long i, long long j)
{
	if (i < j) return j;
	 else return i;
}

struct Work
{
	int end, val;
}work[100005];//每一个活动的结束时间和价值

priority_queue<int,vector<int>,greater<int> > plan;

bool cmp(Work i, Work j)
{
	return i.end < j.end; 
}//排序

int main() 
{
	scanf("%d", &n);
	
	for (int i = 1; i <= n; ++i) 
		scanf("%d%d", &work[i].end, &work[i].val);
	
    sort(work + 1, work + n + 1, cmp);

 	for (int i = 1; i <= n; ++i)
	{ 
		b = 0;
		if (time + 1 <= work[i].end) {
			ans =(long long) ans + work[i].val;
			time++;
			plan.push(work[i].val);
		}//判断有没有空位
		 else
		 {
			if (plan.top() < work[i].val) {
				ans =(long long) ans - plan.top();
				plan.pop();
				plan.push(work[i].val);
				ans =(long long) ans + work[i].val;
			}
		 } //替换

	}
	
	printf("%lld", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/100586456