//目录

LA 4254 贪心

题意:有 n 个工作,他的允许的工作时间是 [l,r] ,工作量是 v ,求CPU最速度的最小值。

分析:

可能太久没有做题了,竟然脑子反应好慢的。还是很容易想到二分,但是二分怎么转移呢?

可以看出,[l,r] 的区间范围不大,可以枚举,cpu 此时的二分答案 x,尽可能的贪心,怎么贪心呢,在同一速度情况下,是最先结束的优先。

而且,这一时刻,他能做很多任务,当 x 很大时,就在这里用优先队列来贪心安排任务。

其实这个题目中的那个图还是有干扰的,因为时时刻刻都要CPU速度为x。

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e4+5;

struct Node {
    int l,r,v;
}p[maxn],u;

bool operator < (Node a,Node b)
{
    return a.r>b.r;
}

int cmp(Node a,Node b) {
    return a.l < b.l;
}

int L,R,sum;
int n;


bool check(int x) {
    priority_queue<Node> Q;
    int k = 0;
    for(int i = L; i <= R; i++) {
        int 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()
{
    freopen("in.txt","r",stdin);
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);

        for(int i = 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;
        int l = 1,r = sum;
        while(l<=r) {
            int mid = (l+r)/2;
            if(check(mid)) {
                r = mid - 1;
                ans = mid;
            }
            else l = mid + 1;
        }
        printf("%d\n",ans);

    }
    return 0;
}

 

posted @ 2018-01-26 14:52  小草的大树梦  阅读(220)  评论(0编辑  收藏  举报