zoukankan      html  css  js  c++  java
  • uva 1153 顾客是上帝(贪心)

    uva 1153 顾客是上帝(贪心)

    有n个工作,已知每个工作需要的时间q[i]和截止时间d[i](必须在此前完成),最多能完成多少个工作?工作只能串行完成,第一项任务开始的时间不早于时刻0.

    这道题算比较难的贪心了。解法是维护一个关于所有选择的时间的大根堆。将所有工作按照截止时间排序(将二维问题转化为一维问题),然后依次考虑每一个工作。如果当前的总时间t,加上当前工作的时间t1,小于等于当前工作的截止时间d1,那么直接把当前工作加入大根堆中。如果t+t1>d1,说明如果做这个工作,就超时了,所以要考虑该不该做这个工作的问题。如果t1<大根堆顶的时间,说明如果把前面的一个工作消除掉,再做这个工作,时间能更短,我们当然选择把这个工作压到堆里去。如果t1>大根堆顶,说明这个工作是不能替换的。

    插一句:贪心真是一种玄学的东西。。很多时候贪心要跟着感觉走,因为根本证明不出来~~~~~

    #include <queue>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=8e5+5;
    
    int T, n;
    priority_queue<int> q;
    struct Work{
        int q, d;
    }w[maxn];
    
    bool cmp1(Work &x, Work &y){
        return x.d<y.d; }
    
    int main(){
        scanf("%d", &T);
        while (T--){
            while (!q.empty()) q.pop();
            scanf("%d", &n);
            for (int i=0; i<n; ++i)
                scanf("%d%d", &w[i].q, &w[i].d);
            sort(w, w+n, cmp1);
            int tott=0, ans=0, maxelmt;
            for (int i=0; i<n; ++i){
                if (tott+w[i].q<=w[i].d){ //如果放的下就放
                    tott+=w[i].q; ++ans;
                    q.push(w[i].q);
                } else {
                    maxelmt=q.top();
                    if (maxelmt>w[i].q){ //如果换了更优就换
                        q.pop(); q.push(w[i].q);
                        tott=tott-maxelmt+w[i].q; }
                }
            }
            printf("%d
    ", ans);
            if (T) puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    WPF Video Tutorials
    英语词汇看病
    回车键的含义
    勘误《新概念》IV
    2010年春季C语言程序设计答疑时间地点安排
    勘误《新概念》III
    A potentially dangerous Request.Form value was detected from the client
    推荐WPF的好书(图书)
    *英语词汇交通
    英语词汇房地产
  • 原文地址:https://www.cnblogs.com/MyNameIsPc/p/8502995.html
Copyright © 2011-2022 走看看