链接:点击读题
Description:
Input:
Output:
题意:给定N个任务,你可以最多同时一起进行K个任务,多进程嘛。然后每个任务都规定了开始时间和结束时间,求最多能够完成多少个任务。
思路:首先,对N个任务,按照结束时间进行区间排序。然后考虑将任务分配到哪一个进程中去处理,第i个进程处理完结束时间用S[i]表示,显然,如果某一个任务的开始时,所有进程都未空闲,此时,任务不能被执行。反正,任务就要被执行,如果这个时候又多个空闲的进程,那么分配到哪个进程中去呢?必然是刚刚结束任务的那个进程,而不是最先空闲的那个进程,因为这个情况下,空闲时间段是最大的。这里要理解理解。【我们WA好几次~~~~】这个时候,问题 就是在 所有进程S中查询 小于当前任务开始时间,并且最接近当前任务开始时间的进程。为了方便维护S的有序性,平衡二叉树!multiset的实现其实就是平衡二叉树!
贴一下代码。
#include <set>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
const int maxn = 100000 + 5;
int n, k;
struct Interval{
int _beg, _end;
bool operator < (const Interval& e) const {
return _end < e._end;
}
};
Interval t[maxn];
int ans;
multiset<int> S;
multiset<int>::iterator it;
int main() {
// freopen("input.txt", "r", stdin);
while(~scanf("%d %d", &n, &k)) {
for(int i = 0; i < n; i++) {
scanf("%d %d", &t[i]._beg, & t[i]._end);
}
sort(t, t + n);
ans = 0;
S.clear();
for(int i = 0; i < k; i++) {
S.insert(0);
}
for(int i = 0; i < n; i++) {
it = S.begin();
if(t[i]._beg < *it) continue;
else if(t[i]._beg == *it) {
S.erase(it);
S.insert(t[i]._end);
}else {
it = S.upper_bound(t[i]._beg);
it--;
S.erase(it);
S.insert(t[i]._end);
}
ans++;
}
printf("%d\n", ans);
}
return 0;
}