首页 > 代码库 > 最高的奖励 【贪心】

最高的奖励 【贪心】

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;
}


最高的奖励 【贪心】