LA 4254 Processor(二分+贪心+优先队列)

来源:互联网 发布:sql删除某一列数据 编辑:程序博客网 时间:2024/05/02 02:19

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


其实刚看到这道题的时候,看到最大值的最小值,首先想到要用二分枚举答案,而且这个想法也十分正确。

但是问题的难点在于如何判断在某个速度下能否完成所有任务,所以必然要有个优先级,什么样的任务应该先做。可以发现如果现在可以选择执行的任务有多个,那么必然要选择结束时间早的任务先执行,这样才能获得最优解。

所以总体的思路就是,将所有任务按照开始时间排序,二分枚举处理器的速度,然后对每个速度进行判断。按照任务开始时间依次加入优先队列,队列优先级是结束时间早的优先。最后就能判断该速度是否能够执行完所有任务。

#include <algorithm>#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <queue>#define INF 0x7fffffffusing namespace std;struct node{    int l,r,v;} p[2000005],u;bool operator < (node a,node b){    return a.r>b.r;}int cmp(node a ,node b){    return a.l<b.l;}int n,L,R,sum;bool check(int x){    int i,t,k=0;    priority_queue<node> Q;    for(i=L; i<=R; i++)    {        t=x;        while(k!=n&&p[k].l<i) Q.push(p[k++]);        while(!Q.empty()&&t!=0)        {            u=Q.top();            Q.pop();            if(u.r<i) return false ;            if(u.v>t)            {                u.v-=t;                t=0;                Q.push(u);            }            else t-=u.v;        }    }    if(Q.empty()) return true;    else return false;}int main(){    int T;    int i,j;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(i=0,sum=0,L=INF,R=0; i<n; i++)        {            scanf("%d%d%d",&p[i].l, &p[i].r, &p[i].v);            R=max(R,p[i].r);            L=min(L,p[i].l);            sum+=p[i].v;        }        sort(p,p+n,cmp);        int ans=INF;         int l,r,mid;        l=1,r=sum;        while(l<=r)        {            mid=(l+r)>>1;            if(check(mid))            {                r=mid-1;                ans=min(ans,mid);            }            else l=mid+1;        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击