【堆】【貪心】Leopard學霸

DescriptionDescription

馬上假期就要到了,THU的神犇Leopard假期裏都不忘學霸,現在有好多門功課,每門功課都耗費他1單位時間來學習。
他的假期從0時刻開始,有1000000000個單位時間(囧rz)。在任意時刻,他都可以任意一門功課(編號1~n)來學習。
因爲他在每個單位時間只能學習一門功課,而每門功課又都有一個截止日期,所以他很難完成所有n門功課。
對於第i門功課,有一個截止時間Di,若他能學完這門功課,他能夠獲得知識Pi。
在給定的功課和截止時間下,Leopard能夠獲得的知識最多爲多少呢?

InputInput

第一行,一個整數n,表示功課的數目
接下來n行,每行兩個整數,Di和Pi

OutputOutput

輸出一行一個整數,表示最多學得的知識數

SampleSample InputInput

3
2 10
1 5
1 7

SampleSample OutputOutput

17

HintHint

【樣例說明】	
第一個單位時間學習第3個功課(1,7)
然後在第二個單位時間學習							
第1個功課(2,10)

TrainTrain ofof ThoughtThought

把每一項活動按結束時間排序, 然後一個個枚舉活動,判斷前面的時間是否可以塞入一個活動,有的話就塞,否則就看是否能與小根堆堆頂(前面所用時間中的單個價值)比較,看是否要交換

CodeCode

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章