题意:有n (n≤800000) 个工作,已知每个工作需要的时间 qi 和截止时间 di (必须在此之前完成),最多能完成多少个工作?工作只能串行完成。第一项任务开始的时间不早于时刻0。(本段摘自《算法竞赛入门经典(第2版)》)
分析:
按照截止时间排序,对于当前工作,如果可以在截止时间之前完成就直接完成,如果不可以的话,从已完成项目中选择一个需要时间最长的取消,将当前工作放进去。对于处理工作时间最长的项目可以用优先队列来实现。
代码:
#include <iostream>
#include <algorithm>
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
using namespace std;
const int maxn = 800000 + 5;
struct node
{
int l, d;
bool operator < (const node& right) const
{
return d < right.d;
}
};
int T, n, t;
node a[maxn];
int main()
{
scanf("%d", &T);
for (int C = 0; C < T; ++C)
{
if (C)
printf("\n");
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%d%d", &a[i].l, &a[i].d);
sort(a, a + n);
t = 0;
priority_queue< int > q;
for (int i = 0; i < n; ++i)
if (t + a[i].l <= a[i].d)
{
t += a[i].l;
q.push(a[i].l);
}
else if (!q.empty())
{
if (q.top() > a[i].l && (t - q.top() + a[i].l <= a[i].d))
{
t -= q.top();
q.pop();
t += a[i].l;
q.push(a[i].l);
}
}
printf("%d\n", q.size());
}
return 0;
}