zoukankan      html  css  js  c++  java
  • [bzoj1572][Usaco2009 Open]工作安排Job_贪心_堆

    工作安排 Job bzoj-1572 Usaco-2009 Open

    题目大意题目链接

    注释:略。


    想法

      我们将任务按照截止时间排序,枚举任务的同时顺便记录出已经做了多少任务(当前时间)。

      对于当前的一个任务,如果当前的时间没有到它的截止时间,我们就做这个任务,并且扔到堆里。堆是按照权值的小根堆。如果当前的时间已经大于等于它的截止时间,我们把当前任务的权值和堆顶的权值进行比较:如果当前任务的权值比堆顶权值大,弹掉堆顶,加上两个任务的贡献差,将当前任务扔进堆里。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define N 100010 
    using namespace std; typedef long long ll;
    struct In{ll val; bool operator < (const In &x) const {return val>x.val;}};
    priority_queue<In>q;
    ll ans=0; int now=0;
    struct Node {ll p; int d;}a[N]; inline bool cmp(const Node &x,const Node &y) {return x.d<y.d;}
    inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
    ll rd() {ll x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;}
    int main()
    {
        int n=rd(); for(int i=1;i<=n;i++) a[i].d=rd(),a[i].p=rd(); sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)
        {
            if(now<a[i].d) {ans+=a[i].p; q.push((In){a[i].p}); now++;}
            else if(a[i].p>q.top().val) {ans+=a[i].p-q.top().val; q.pop(); q.push((In){a[i].p});}
        }
        printf("%lld
    ",ans);
    }
    

    小结:用堆来实现正确的贪心是一种非常常见的套路。

  • 相关阅读:
    排序题目
    力扣二分法题目
    力扣动态相似题目
    875爱吃香蕉的珂珂
    410分割数组的最大值
    1335工作计划的最低难度
    287寻找重复数
    69X的平方根
    力扣相似题目
    解决Linux虚拟机内 /mnt/hgfs路径下文件为空问题
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9661871.html
Copyright © 2011-2022 走看看