(intermediate) UVA 贪心+二分+优先队列 1422Processor

来源:互联网 发布:什么是玛丽苏剧情 知乎 编辑:程序博客网 时间:2024/05/02 00:43

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 wishould be done on the processor within the interval [ridi] 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 [ridi] and work wi , i = 1,..., 5 , where [r1,d1] = [1, 4] , [r2d2] = [3, 6] , [r3d3] = [4, 5] , [r4d4] = [4, 7] , [r5d5] = [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


TLE x 1  WA x 8 AC 1 独立解决。


题意:有一个时间段里面会有些任务需要你分配给CPU,每个任务需要在特定时间内完成,但是他们每个任务的时间不必连续,然后CPU的消耗当然要越低越好啦,每个任务有一定的计算量,你需要在它的时间内完成一定量的计算,你要算处每秒的计算量最少要多少才能完成这些任务。


思路:我们先来考虑一下两个任务之间的关系,如果他们没有交集,那么他们没有什么关系,如果一个任务的时间段被另一个包起来了,那么这个被包起来的任务我们有先算出来,然后在算包住它的任务,如果两个任务的时间段只是相交怎么办呢?我们只需要按时间的顺序,先完成左边的任务,然后再完成右边的任务即可。根据这三个情况我们想想代码要怎么写呢? 首先我们把所有的任务按开始时间从小到大排序,模拟我们是CPU按照时间的先后接纳每一个任务,然后由于我们要优先算那种被包含的,假设我们加入一个任务的时候,它的结束时间比上一个任务的结束时间要早,那么我们就先去计算这个任务,这时候我们想到了优先队列,这个优先队列是按照结束时间从小到大排,考虑我们正处于的时间是L,那么我们手上有若干个任务,我们优先计算那些早结束的,是吧?如果早结束的任务你马上做都不能完成,那么推到后面就更加不可能完成了。到这里我们要用到的数据结构和基本思路都有了。 除此之外,我们可以二分CPU的最大计算速度,判断是否能完成所有的任务。到这为止,我们的解题思路已经出来了,动起你的手打代码吧。


代码:

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<algorithm>#include<queue>#include<stdlib.h>using namespace std;#define LL long longconst int maxn=30000+5;const int inf=1e9;inline int max(int a,int b) { return a>b?a:b; }inline int min(int a,int b) { return a<b?a:b; }struct Task{    int l,r,w;    Task(int l=0,int r=0,int w=0)    :l(l),r(r),w(w) {}    bool operator<(const Task&tk) const    {        return l<tk.l;    }}task[10000+5];int w[10000+5];struct Comp{    bool operator()(const int&tk1,const int&tk2) const    {        return task[tk1].r>task[tk2].r;    }};vector<int> v[20000+5];int n;int X[20000+5],c;void input(){    scanf("%d",&n);    c=0;    for(int i=0;i<n;++i)    {        int L,R,W;        scanf("%d%d%d",&L,&R,&W);        task[i]=Task(L,R,W);        X[c++]=L;        X[c++]=R;    }    sort(X,X+c);    c=unique(X,X+c)-X;    sort(task,task+n);//    for(int i=0;i<n;++i)//        printf("%d %d %d\n",task[i].l,task[i].r,task[i].w);    for(int i=0;i<c;++i) v[i].clear();    for(int i=0;i<n;++i)    {        int p=lower_bound(X,X+c,task[i].l)-X;        v[p].push_back(i);    }}LL rest[20000+5];bool ok(int up){    for(int i=0;i<n;++i) w[i]=task[i].w;    for(int i=0;i<c-1;++i) rest[i]=(LL)up*(X[i+1]-X[i]);    priority_queue<int,vector<int>,Comp> q;    for(int i=0;i<c-1;++i)    {        while(q.size())        {            int x=q.top();            if(task[x].r<=X[i])            {                if(w[x]>0) return false;                q.pop();            }            else break;        }        for(int j=0;j<v[i].size();++j)            q.push(v[i][j]);        while(q.size()&&rest[i])        {            int x=q.top();            if(w[x]>=rest[i])            {                w[x]-=rest[i];                rest[i]=0;            }            else            {                rest[i]-=w[x];                w[x]=0;            }            if(w[x]==0) q.pop();        }    }    while(q.size())    {        int x=q.top();        if(task[x].r<=X[c-1])        {            if(w[x]>0) return false;            q.pop();        }        else break;    }    return true;}void solve(){    int left=0,right=1e8;    int ans=inf;    while(left<=right)    {        int mid=(left+right)>>1;        if(ok(mid))        {            ans=min(ans,mid);            right=mid-1;        }        else left=mid+1;    }    printf("%d\n",ans);}int main(){   // GetData(); return 0; //freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout);    int T;cin>>T;    while(T--)    {        input();        solve();    }}/*10101 5 31 2 23 4 14 7 65 6 35 8 26 9 36 10 47 10 28 13 9*/


0 0