1163 最高的奖励
基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励。在结束时间之前完成该任务,就可以获得对应的奖励。完成每一个任务所需的时间都是1个单位时间。有时候完成所有任务是不可能的,因为时间上可能会有冲突,这需要你来取舍。求能够获得的最高奖励。
Input
第1行:一个数N,表示任务的数量(2 <= N <= 50000)
第2 - N + 1行,每行2个数,中间用空格分隔,表示任务的最晚结束时间E[i]以及对应的奖励W[i]。(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9)
Output
输出能够获得的最高奖励。
Input示例
7
4 20
2 60
4 70
3 40
1 30
4 50
6 10
Output示例
230
贪心
考虑2种策略
①:将结束时间按从小到大排序,维护一个t表示当前时间 score表示得分
t < E[i]时 将w[i]放进一个最小优先队列 score+=w[i]
t > E[i]时 比较小顶堆堆顶元素 如果w[i]>堆顶 显然 i任务必然可以在堆顶元素占用的时间段完成 所以用i任务替换堆顶的任务
②:按奖励从大到小排序,将任务i放在 满足t<=E[i] t时间未被使用的最大的t
偷懒直接把被使用过的时间放set里 显然复杂度可能退化到O(n^2) TLE
注意只有50000个任务 当任务截止时间>50000时 可以直接把截止时间设置为50000
并查集 par[i]表示t<=i的 最大的t且未被使用的t
//①
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<time.h>
#include<math.h>
#include<list>
#include<cstring>
#include<fstream>
#include<bitset>
//#include<memory.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define INF 1000000007
const int N=50000+5;
pii a[N];
int main()
{
//freopen("/home/lu/文档/r.txt","r",stdin);
//freopen("/home/lu/文档/w.txt","w",stdout);
int n;
scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%d%d",&a[i].first,&a[i].second);
sort(a,a+n);
priority_queue<int,vector<int>,greater<int> >que;
ll score=0;
int t=0;
for(int i=0;i<n;++i){
if(t<a[i].first){
++t;
que.push(a[i].second);
score+=a[i].second;
}
else{
if(a[i].second>que.top()){
score+=a[i].second-que.top();
que.pop();
que.push(a[i].second);
}
}
}
cout<<score<<endl;
return 0;
}
//②
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<time.h>
#include<math.h>
#include<list>
#include<cstring>
#include<fstream>
#include<bitset>
//#include<memory.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define INF 1000000007
const int N=50000+5;
pii a[N];
int par[N];
inline int find(int i){
return i==par[i]?i:par[i]=find(par[i]);
}
inline void unite(int fr,int to){
par[find(fr)]=par[find(to)];
}
int main()
{
//freopen("/home/lu/文档/r.txt","r",stdin);
//freopen("/home/lu/文档/w.txt","w",stdout);
int n;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d%d",&a[i].second,&a[i].first);
a[i].second=min(50000,a[i].second);
par[i]=i;
}
par[50000]=50000;
sort(a,a+n,greater<pii>());
ll score=0;
for(int i=0,t;i<n;++i){
if(t=find(a[i].second)){
score+=a[i].first;
unite(t,t-1);
}
}
cout<<score<<endl;
return 0;
}