LA4254(二分+贪心+优先队列)

题目:有n个任务,每个任务有三个参数ri,di,wi,表示任务i必须在[ri, di]内执行完,现有一台处理器,处理器执行的速度可以变化,速度为s时,一个工作量为wi的任务执行的时间为w/s,任务不一定连续执行,现在要求求出处理器在执行过程中最大速度的最小值。

分析:首先一定是个二分,所以主要的地方在于check函数怎么写。假设某一时刻的速度为v,不难想到,如果贪心的选择结束时间距离当前时刻最近的任务执行(这里需要用到优先队列),一定是最优的,并且这样还可以避免浮点数运算。
ps:优先队列使用

代码如下:

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#define db double
using namespace std;

const int maxn = 10000 + 10;
const int INF = (int)1e9;

struct node {
    int l, r, w;
    bool operator < (const node &a) const {
        return r > a.r;
    }

}A[maxn];
int n, mint, maxt;

priority_queue<node> Q;

bool cmp(node a, node b) {
    return a.l < b.l || (a.l == b.l && a.r < b.r);
}

bool check(int var) {
    while (!Q.empty()) Q.pop();

    int pos = 0;
    for (int tim = mint; tim < maxt; tim ++) {
        while (pos < n && A[pos].l <= tim) Q.push(A[pos++]);

        while (!Q.empty() && var) {
            node tmp = Q.top(); Q.pop();
            if (tmp.l < tim) {
                tmp.l = tim;
                Q.push(tmp);
                continue;
            }
            if (tmp.r <= tim) return false;
            if (tmp.w <= var) var -= tmp.w;
            else {
                tmp.w -= var;
                Q.push(tmp);
                break;
            }
        }

    }
    return Q.empty();
}

int main(){
    freopen("a.in", "r", stdin);
    freopen("a.out", "w", stdout);

    int T; scanf("%d", &T);
    while (T --) {
        scanf("%d", &n);
        int sumw = 0;
        mint = INF, maxt = 0;
        for (int i = 0; i < n; i ++) {
            scanf("%d %d %d", &A[i].l, &A[i].r, &A[i].w);
            sumw += A[i].w;
            mint = min(mint, A[i].l);
            maxt = max(maxt, A[i].r);
        }
        sort(A, A + n, cmp);
        int L = 0, R = sumw, ans;
        while (L <= R) {
            int M = L + (R-L) / 2;
            if (check(M)) {
                ans = M;
                R = M - 1;
            } else L = M + 1;
        }
        printf("%d\n", ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37577390/article/details/81839836