uva1422 - Processor 二分+优先队列

An ``early adopter" Mr. Kim bought one of the latest notebooks which has a speed-controlled processor. The processor is able to operate at variable speed. But the higher the speed, the higher the power consumption is. So, to execute a set of programs, adjusting the speed of the processor dynamically results in energy-efficient schedules. We are concerned in a schedule to minimize the maximum speed of the processor.

The processor shall execute a set of programs and each program Pi is given having a starting time ri , a deadline di , and work wi . When the processor executes the programs, for each program Pi , the work wi should be done on the processor within the interval [ri, di] to complete Pi . Also, the processor does not have to execute a program in a contiguous interval, that is, it can interrupt the currently running program and later resume it at the interrupted point. It is assumed that ri , di , and wi are given positive integers. Recall that the processor can execute the programs at variable speed. If the processor runs the program Pi with work wi at a constant speed s ,then it takes $ {\frac{​{w_{i}}}{​{s}}}$ time to complete Pi . We also assume that the available speeds are positive integers, that is, the processor operates only at integer points of speed. The speed is unbounded and the processor may operate at sufficiently large speeds to complete all the programs. The processor should complete all the given programs and the goal is to find a schedule minimizing the maximum of the speeds at which the processor operates.

For example, there are five programs Pi with the interval [ri, di] and work wi , i = 1,..., 5 , where [r1, d1] = [1, 4] , [r2, d2] = [3, 6] , [r3, d3] = [4, 5] , [r4, d4] = [4, 7] , [r5, d5] = [5, 8] and w1 = 2 , w2 = 3 , w3 = 2 , w4 = 2 , w5 = 1 . Then the Figure 1 represents a schedule which minimizes the maximum speed at which the processor operates. The maximum speed is 2 in this example.

=6in \epsfbox{p4254.eps}

Input 

Your program is to read from standard input. The input consists of T test cases. The number of test cases T (1$ \le$T$ \le$20) is given on the first line of the input. The first line of each test case contains an integer n (1$ \le$n$ \le$10, 000) , the number of given programs which the processor shall execute. In the next n lines of each test case, the i -th line contain three integer numbers ri , di , and wi , representing the starting time, the deadline, and the work of the program Pi , respectively, where 1$ \le$ri < di$ \le$20, 000 , 1$ \le$wi$ \le$1, 000 .

Output 

Your program is to write to standard output. Print exactly one line for each test case. The line contains the maximum speed of a schedule minimizing the maximum speed at which the processor operates to complete all the given programs.

Sample Input 

3 
5 
1 4 2 
3 6 3 
4 5 2 
4 7 2 
5 8 1 
6 
1 7 25 
4 8 10 
7 10 5 
8 11 5 
10 13 10 
11 13 5 
8 
15 18 10 
20 24 16 
8 15 33 
11 14 14 
1 6 16 
16 19 12 
3 5 12 
22 25 10

Sample Output 

2 
5 
7

  有N个任务,每个任务必须在[ri,di]的时间内完成,并且有个工作量wi,完成这个任务需要wi/S秒的时间,S是速度,是个整数,也就是1秒内能完成S的量。问完成全部任务最小速度是多少。

  速度最大是10000*1000,最小是1。可以用二分法求临界值。问题难在怎么判断一个速度是否能完成全部任务。从第1秒开始往后枚举每一秒,这一秒做当前还没完成的并且结束时间最早的任务一定是最优的。如果这一秒做完这个任务还有剩余的时间,那么就做下一个结束时间最早的任务。这个题虽然看似wi/S可能不是整数,但是整个过程中不影响,用wi-S就是1秒做这个任务之后这个任务还剩多少工作量。如果最后所有工作都完成了就说明这个速度满足要求。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define INF 0x3f3f3f3f
#define MAXN 10010
#define MAXM 60
#define eps 1e-9
#define pii pair<int,int>
using namespace std;
int T,N,MAXT;
struct duty{
    int r,d,w;
    bool operator < (const duty &x) const{
        return d>x.d;
    }
}work[MAXN];
bool cmp(duty a,duty b){
    return a.r<b.r;
}
int check(int speed){
    int i=0;
    priority_queue<duty> q;
    for(int t=1;t<MAXT;t++){
        int sum=speed;
        for(;i<N&&work[i].r<=t;i++) q.push(work[i]);  //开始时间在t秒或之前的
        while(sum&&!q.empty()){
            duty temp=q.top();
            q.pop();
            if(temp.d<=t) return 0;   //最早结束的不能做完
            if(temp.w>sum){           //这一秒不能完成这个任务,工作量减去这一秒的工作量
                temp.w-=sum;
                q.push(temp);
                sum=0;
            }
            else sum-=temp.w;         //任务完成,可能还剩余时间(工作量)
        }
        if(i==N&&q.empty()) return 1;
    }
    return 0;
}
int bsearch(int L,int R){            //区间[L,R]
    int m;
    while(L<R){
        m=(L+R)/2;
        if(check(m)) R=m;
        else L=m+1;
    }
    return L;
}
int main(){
    freopen("in.txt","r",stdin);
    scanf("%d",&T);
    while(T--){
        priority_queue<duty> q;
        scanf("%d",&N);
        int r,d,w;
        MAXT=0;
        for(int i=0;i<N;i++){
            scanf("%d%d%d",&work[i].r,&work[i].d,&work[i].w);
            MAXT=max(MAXT,work[i].d);
        }
        sort(work,work+N,cmp);
        printf("%d\n",bsearch(1,10000010));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值