• 洛谷——P4053 [JSOI2007]建筑抢修


    P4053 [JSOI2007]建筑抢修

    小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。

    对于每一个数相当于有了两个标准,单纯排序过这道题是不可能的

    首先按照$t_2$排序,再次按照$t_1$贪心模拟,

    若当前的$T$所用总时间$>t_2$,考虑将前面$t_1$时间最大的哪个去除,转而添加当前$t_1$(若当前$t_1$比前面的小的话)

    可以发现,若总时间超过,你去掉那个最大值,会使总时间减小,对后面的影响减小

    用堆维护这个最大值即可

    #include<bits/stdc++.h>
    
    #define N 1500000
    using namespace std;
    
    int n,ans;
    struct node{
        int t1,t2;
    }e[N];
    
    bool cmp(node A,node B){
        return A.t2==B.t2 ? A.t1<B.t1 : A.t2<B.t2;
    }
    
    priority_queue<int>Q;
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&e[i].t1,&e[i].t2);
        
        sort(e+1,e+1+n,cmp);
        
        int T=0;
        for(int i=1;i<=n;i++){
            if(T+e[i].t1<=e[i].t2){
                T+=e[i].t1;
                ++ans;
                Q.push(e[i].t1);
            }else{
                if(!Q.empty()&&e[i].t1<Q.top()){
                    T=T-Q.top()+e[i].t1;
                    Q.pop();
                    Q.push(e[i].t1);
                }
            }
        }
        
        printf("%d
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    2804 最大最小数质因数
    5429 多重背包
    1851 越狱
    Gvim使用
    3622 假期
    4906 删数问题
    2845 排序的代价
    poj 3352
    常用正则表达式汇总
    功能简单例子
  • 原文地址:https://www.cnblogs.com/song-/p/9814317.html
Copyright © 2020-2023  润新知