题目链接:https://vjudge.net/problem/UVA-1153
题目大意:有n(n≤800000)个工作,已知每个工作需要的时间qi和截止时间di(必须在此之前完成),最多能完成多少个工作?工作只能串行完成。第一项任务开始的时间不早于时刻0。
思路:将任务按照截止时间排序,对于每个任务,若满足要求就直接完成,若不满足要求,则从已完成任务中选取一个时间最长的取消,将当前的工作放进去,这个过程可以用优先队列来完成。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include<cctype>
#include <cstdlib>
#include<map>
#include<iostream>
#include<queue>
using namespace std;
typedef long long LL;
const int dr[] = {0,0,-1,1};
const int dc[] = {-1,1,0,0};
const int maxn = 800000 + 10;
struct Node
{
int q, d;
Node(int q = 0, int d = 0) : q(q), d(d) {}
bool operator < (const Node& rhs) const {
return d < rhs.d;
}
}node[maxn];
struct cmp
{
bool operator () (const Node& A, const Node& B) {
return A.q < B.q;
}
};
priority_queue<Node, vector<Node>, cmp> q;
int main()
{
int T, n;
scanf("%d", &T);
while(T--)
{
while(!q.empty()) q.pop();
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d%d", &node[i].q, &node[i].d);
sort(node, node+n);
int ans = 0, t = 0;
for(int i = 0; i < n; i++) {
if(t + node[i].q <= node[i].d) { ++ans; t += node[i].q; q.push(node[i]); }
else if(!q.empty()) {
int tt = t - q.top().q + node[i].q;
if(tt < t) {
q.pop();
q.push(node[i]);
t = tt;
}
}
}
printf("%d\n", ans);
if(T) printf("\n");
}
return 0;
}