题意:有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; }