uva1153 Keep the Customer Satisfied

贪心加优先队列 (默认是小的在前,正好)

//这里又很套路,设队列里的都是符合条件的考虑新加入的即可。再处理一下空队列的情况。很完美//

截止时间短的在前面,干的就多
先根据截止日期排序
优先队列根据完成所需时间排序
首先队列里的都是能完成的
策略:新加入的,如果在前面的完成后仍能完成,就直接加进去;不能,因为截止日期在更后,不影响其他的,比较top元素用的时间,更短就换掉(此时因为截止日期靠后,用的时间还短,所以能成立)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;

const int MAXN = 800005;
const int N = 2000005;

struct order{
    int q, d;
    bool operator < (const order &a) const {
        return q<a.q;
}
}o[MAXN];

int cmp (order a, order b) {
    return a.d < b.d;
}

int n;
int solve() {
    priority_queue<int> done;
    int sum = 0, temp;
    for (int i = 0; i < n; i++) {
        if (o[i].q + sum <= o[i].d) {
            done.push(o[i].q);
            sum += o[i].q;
        }
        else if (!done.empty()){
            temp = done.top();
            if (temp > o[i].q) {
                sum = sum - temp + o[i].q;
                done.pop();
                done.push(o[i].q);
            }
        }
    }
    return done.size();
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &n);
        for (int i = 0; i < n; i++)
            scanf("%d%d", &o[i].q, &o[i].d);
        sort(o, o + n, cmp);
        printf("%d\n", solve());
        if(T)
            printf("\n");
    }
    return 0;
}

 

posted @ 2018-10-05 19:20  Erio  阅读(155)  评论(0编辑  收藏  举报