UVALive - 4254 Processor 二分+优先队列

来源:互联网 发布:组态软件开发源代码 编辑:程序博客网 时间:2024/05/02 00:55

题目大意:有n个任务,每个任务有三个参数,ri,di和wi,表示必须在时刻[ri,di]之内执行,工作量为wi,处理器的执行速度可以变化,当执行速度为s时,一个工作量为wi的人物需要执行w/s个单位时间,另外,任务不一定要连续执行,可以分成若干块,你的任务是求出处理器执行过程中最大速度的最小值

解题思路:最大值的最小问题,用二分枚举。

这里有一个条件,必须要在任务的[ri,di]之内执行,那么现在的问题就是任务的执行顺序了。最优的情况是,di小的先执行(必须现在的执行时间大于ri)。所以设置一个优先队列,队列按di的大小进行排序,然后按一个个单位时间来完成所需的任务

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;#define maxn 10010struct Process{int r, d, w;bool operator <(const Process t) const {return d > t.d;}}P[maxn];priority_queue<Process> q;int n;int cmp(const Process a, const Process b) {return a.r < b.r;}bool check(int speed) {while(!q.empty())q.pop();int start = 0, time = 1;while(1) {while(start < n && P[start].r < time) q.push(P[start++]);int tmp = speed;while(tmp && !q.empty()) {Process t = q.top();q.pop();int MIN = min(t.w,tmp);tmp -= MIN;t.w -= MIN;if(t.w > 0)q.push(t);}time++;if(!q.empty() && q.top().d < time)return false;if(q.empty() && start == n)return true;}}int main() {int test;scanf("%d",&test);while(test--) {int sum = 0;scanf("%d",&n);for(int i = 0; i < n; i++) {scanf("%d%d%d",&P[i].r, &P[i].d, &P[i].w);sum += P[i].w;}sort(P,P+n,cmp);int left = 0, right = sum;while(left < right) {int mid = (left + right) / 2;if(check(mid))right = mid;elseleft = mid + 1;}printf("%d\n",left);}return 0;}


0 0