题意:有n个任务,给出了每个任务的起始时间和终止时间还有工作量w,处理任务的速度为s时,任务会花费 w / s时间,然后每个任务都要在规定时间内完成,但任务可以不用连续时间块内完成,要求出让所有时间都顺利完成的最大速度的最小值。
题解:一般要求最大XX最小值时用二分法,可以二分出一个速度,拿去判断是否可行。在判断一个速度是否可以使任务完成时,用一个优先队列(终止时间小的排在前面)存所有未完成且可以开始进行的所有任务,然后模拟每一秒的任务量让优先级最大的任务先用,如果用不完就次之,然后如果任务未完成就继续加入队伍,最后如果所有任务都完成就true,超出时间就false。
#include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 10005;
struct P {
int st, en, w;
friend bool operator < (const P &a, const P &b) {
return a.en > b.en;
}
}p[N];
int n;
int cmp(P a, P b) {
return a.st < b.st;
}
bool judge(int x) {
priority_queue<P> q;
int t = 1, i = 0;
while (1) {
while (i < n && t >= p[i].st)
q.push(p[i++]);
int re = x;
while (re != 0 && !q.empty()) {
P u = q.top();
q.pop();
int temp = min(re, u.w);
re -= temp;
u.w -= temp;
if (u.w != 0)
q.push(u);
}
t++;
if (!q.empty() && q.top().en <= t)
return false;
if (q.empty() && i == n)
return true;
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
int l = 0, r = N;
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &p[i].st, &p[i].en, &p[i].w);
}
sort(p, p + n, cmp);
while (l < r) {
int mid = (l + r) / 2;
if (judge(mid))
r = mid;
else
l = mid + 1;
}
printf("%d\n", l);
}
return 0;
}