D e s c r i p t i o n Description Description
马上假期就要到了,THU的神犇Leopard假期里都不忘学霸,现在有好多门功课,每门功课都耗费他1单位时间来学习。
他的假期从0时刻开始,有1000000000个单位时间(囧rz)。在任意时刻,他都可以任意一门功课(编号1~n)来学习。
因为他在每个单位时间只能学习一门功课,而每门功课又都有一个截止日期,所以他很难完成所有n门功课。
对于第i门功课,有一个截止时间Di,若他能学完这门功课,他能够获得知识Pi。
在给定的功课和截止时间下,Leopard能够获得的知识最多为多少呢?
I n p u t Input Input
第一行,一个整数n,表示功课的数目
接下来n行,每行两个整数,Di和Pi
O u t p u t Output Output
输出一行一个整数,表示最多学得的知识数
S a m p l e Sample Sample I n p u t Input Input
3
2 10
1 5
1 7
S a m p l e Sample Sample O u t p u t Output Output
17
H i n t Hint Hint
【样例说明】
第一个单位时间学习第3个功课(1,7)
然后在第二个单位时间学习
第1个功课(2,10)
T r a i n Train Train o f of of T h o u g h t Thought Thought
把每一项活动按结束时间排序, 然后一个个枚举活动,判断前面的时间是否可以塞入一个活动,有的话就塞,否则就看是否能与小根堆堆顶(前面所用时间中的单个价值)比较,看是否要交换
C o d e Code 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;
}