1163 . 最高的奖励
基准时间限制:1 秒 空间限制:65536 KB 分值: 20
有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
这道题和nyoj 1107 一样可是就是不知道为什么递交就TL呢————
分析:贪心思想, 但是会用到路径压缩来缩短查找用的时间
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL __int64
#define M 50500
using namespace std;
struct node{
LL t;
LL v;
}s[M];
LL a[M], p[M], c[M];
bool cmp(node a, node b){
return a.v > b.v;
}
LL bis(LL v, LL left, LL right){
LL mid;
while(left <= right){
mid = (left+right)>>1;
if(a[mid] == v) return mid;
else if(a[mid] < v) left = mid+1;
else right = mid-1;
}
return -1;
}
int main(){
LL n;
while(scanf("%I64d", &n) == 1){
LL i, j;
for(i = 0; i < n; i ++){
scanf("%I64d%I64d", &s[i].t, &s[i].v);
a[i] = s[i].t;
}
a[n] = 0;
for(i = 0; i < n+5; i ++){
p[i] = i-1;
}
sort(s, s+n, cmp);
sort(a, a+n+1);
LL sum = 0;
LL cou = 0;
memset(c, 0, sizeof(c));
for(i = 0; i < n; i ++){
if(cou >= a[n]-a[0]) break;
LL k = bis(s[i].t, 0, n);
for(j = k; j >= 1; j= p[j]){
if(c[j] < a[j]-a[j-1]){
c[j]++; sum += s[i].v;
p[k] = min(k-1, j);
break;
}
}
}
printf("%I64d\n", sum);
}
return 0;
}