题意:有n个任务,每个任务有三个参数,r,d,w,表示该任务必须在[r,d]之间执行,工作量是w,处理器执行速度可以变化,当执行速度是s的时候,一个工作量是w的任务需要需要的执行时间是w/s个工作单位,另外,任务不一定要连续的执行,可以分成若干块,求出处理器执行过程中最大速度的最小值,速度必须是整数
思路:最大值的最小值用二分处理,对于一个速度来说,我们可以考虑它在单位时间能做的事,定义两个变量,一个代表处理了的任务个数,一个代表当前的时间,我们没一个单位时间的递加,对于未处理或者未处理完的一个任务如果它的 l 的大小还小于当前的 j,那么我们就可以处理它,至于处理的先后顺序是按 r 从小到大,很容易贪心证明,那么对于一个任务我们每次都减去它所能处理的最大值,如果当前还有没有处理的任务且它的 r 值大于等于当前时间的话,那么这个速度是不行的,都处理的话,就可以了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int MAXN = 10005;
struct node{
int l,r,w;
bool operator <(const node &a)const {
return r > a.r;
}
}arr[MAXN];
int n,ans;
priority_queue<node> q;
bool cmp(node a,node b){
return a.l < b.l;
}
bool check(int mid){
int i = 0, j = 0;
while (!q.empty())
q.pop();
while (1){
while (i < n && arr[i].l <= j)
q.push(arr[i++]);
int now = mid;
while (now != 0 && !q.empty()){
node temp = q.top();
q.pop();
int m = min(now,temp.w);
now -= m;
temp.w -= m;
if (temp.w != 0)
q.push(temp);
}
j++;
if (!q.empty() && q.top().r <= j)
return false;
if (q.empty() && i == n)
return true;
}
}
int main(){
int t;
scanf("%d",&t);
while (t--){
scanf("%d",&n);
int sum = 0;
for (int i = 0; i < n; i++){
scanf("%d%d%d",&arr[i].l,&arr[i].r,&arr[i].w);
sum += arr[i].w;
}
sort(arr,arr+n,cmp);
int l = 0,r = sum;
while (l <= r){
int mid = (l+r)>>1;
if (check(mid)){
ans = mid;
r = mid - 1;
}
else l = mid + 1;
}
printf("%d\n",ans);
}
return 0;
}