题目
N
N
N个任务,每个任务完成时限为
T
i
Ti
Ti,要一个单位时间完成,奖励为
W
i
Wi
Wi,求能获得的最多奖励。
输入
第一行一个整数
N
N
N,表示需要完成的任务数目。
接下来
N
N
N行,每行两个整数
T
T
T、
W
W
W,分别表示完成这个任务的最后期限和获得的奖励。
输出
输出数据有且仅有一行,只包含一个整数,表示最多获得的奖励。
数据
对于
10
10
10%的数据,
N
≤
100
,
T
i
≤
100
,
W
i
≤
2000
N≤100,Ti≤100,Wi≤2000
N≤100,Ti≤100,Wi≤2000。
对于
30
30
30%的数据,
N
≤
1000
,
T
i
≤
5000
,
W
i
≤
2000
N≤1000,Ti≤5000,Wi≤2000
N≤1000,Ti≤5000,Wi≤2000。
对于
50
50
50%的数据,
N
≤
10000
,
T
i
≤
20000
,
W
i
≤
2000
N≤10000,Ti≤20000,Wi≤2000
N≤10000,Ti≤20000,Wi≤2000。
对于
100
100
100%的数据,
N
≤
200000
,
T
i
≤
200000
,
W
i
≤
2000
N≤200000,Ti≤200000,Wi≤2000
N≤200000,Ti≤200000,Wi≤2000。
时间限制:
1000
m
s
1000 ms
1000ms
内存限制:
262144
K
B
262144 KB
262144KB
样例
input
5
2 3
1 2
4 5
1 3
3 4
output
15
题解
将所有的任务按照时间从大到小排。保证堆中任务符合时间的要求。
将时间从大到小往前轮,放进队列,保证轮到时间a时,没被分配且0能在时间a完成的任务全部在大根堆中。
每次选择奖励最多的任务完成即可。
代码
#include<bits/stdc++.h>
using namespace std;
struct psx{ int t, v; } a[200010];
priority_queue<int> q;
bool mycmp(psx a,psx b){ return a.t > b.t; }
int n, N, ans, y;
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d%d",&a[i].t,&a[i].v),
N = max(a[i].t, N);
sort(a+1, a+1+n, mycmp);
for(int i = N; i; i--) {
while(a[++y].t >= i) q.push(a[y].v); y--;
if(!q.empty()) ans += q.top(), q.pop();
}
printf("%d", ans);
return 0;
}