UVa:1422 Processor

二分+贪心。

二分答案,然后需要判断该速度时能否完成所有任务。每次优先去做结束时间早的任务。这样从1开始枚举每个时刻,如果该时刻是某任务的左端点就把它放进优先队列,然后每一秒优先去做结束时间早的任务。这里有个非常恶心的地方,如果你在这一秒内完成了这个任务,但是这一秒还没有结束,那么你可以把余下的时间去做另一个任务。用另一种角度阐述就是,如果某一秒速度v>某任务的工作量w,那么多出来的(v-w)这一块速度可以继续去干别的,直到这段速度全部用完或者没有任务可干。

判断的时候有两个地方,一是如果在某时刻队列中还存在结束时间比该时刻早的任务,那么这个速度肯定是小了。二是所有时间结束后队列非空,说明速度小了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define MOD 20071027
#define MAXN 20005
using namespace std;
int minn,maxn;
struct Task
{
    int w,l,r;
    Task(int a=0,int b=0,int c=0):w(a),l(b),r(c) {}
    bool operator < (const Task &p) const
    {
        return r>p.r;
    }
};
vector<Task> vec[MAXN];
void process(priority_queue<Task> &pq,int v)
{
    if(!pq.empty())
    {
        Task t=pq.top();
        pq.pop();
        t.w-=v;
        if(t.w>0) pq.push(t);
        else
        {
            while(t.w<0&&!pq.empty())
            {
                Task tt=pq.top();
                pq.pop();
                tt.w+=t.w;
                if(tt.w>0)   pq.push(tt);
                t.w=tt.w;
            }
        }
    }
}
void Init()
{
    for(int i=0; i<=20000; ++i)
        vec[i].clear();
}
bool Judge(int v)
{
    priority_queue<Task> pq;
    for(int i=minn; i<=maxn; ++i)
    {
        if(!pq.empty()&&pq.top().r<=i) return false;
        for(int j=0; j<vec[i].size(); ++j)
            pq.push(vec[i][j]);
        process(pq,v);
    }
    if(pq.empty()) return true;
    else return false;
}
int Bsearch(int low,int high)
{
    int mid=(low+high)>>1;
    while(low<high)
    {
        if(Judge(mid)) high=mid;
        else low=mid+1;
        mid=(low+high)>>1;
    }
    return mid;
}
int main()
{
    //freopen("shuju.txt","r",stdin);
    //  freopen("myout.txt","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        minn=INF;
        maxn=0;
        Init();
        int x,y,z;
        for(int i=0; i<n; ++i)
        {
            scanf("%d%d%d",&x,&y,&z);
            minn=min(minn,x);
            maxn=max(maxn,y);
            vec[x].push_back(Task(z,x,y));
        }
        int ans=Bsearch(1,1000);
        printf("%d\n",ans);
    }
    return 0;
}


 

你可能感兴趣的:(二分法,贪心)