【BZOJ1572】【usaco 2009 open】工作安排job

【问题描述】

    Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间。 他的工作日从0时刻开始,有1000000000个单位时间(!)。在任一时刻,他都可以选择编号1~N的N(1 <= N <= 100000)项工作中的任意一项工作来完成。 因为他在每个单位时间里只能做一个工作,而每项工作又有一个截止日期,所以他很难有时间完成所有N个工作,虽然还是有可能。 对于第i个工作,有一个截止时间D_i(1 <= D_i <= 1000000000),如果他可以完成这个工作,那么他可以获利P_i( 1<=P_i<=1000000000 ). 在给定的工作利润和截止时间下,FJ能够获得的利润最大为多少呢?答案可能会超过32位整型。

【分析】

    贪心。先将工作按截止时间排序。添加一个时间在0时间,且截止时间为0利润为0,维护一个时间和堆。初始状态下,时间设为极大值。只要当前时间大于当前事件的截止时间,便取出堆顶,利润增加,时间减一。再让时间等于当前事件的截止时间,把当前事件的利润加入堆。

   详见代码。

    顺便一提,c++可以直接用priority_queue做大根堆,就省打了很多。

【代码】

    

//bzoj1572(lydsy)
//usaco 09 open



#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;

priority_queue<long long, vector<long long> >q;


struct apair
{
    int d;int  p;
}a[100050];

bool operator < (const apair& lhs,const apair& rhs)
{return lhs.d < rhs.d;}

int n;
int main()
{
    freopen("job.in","r",stdin);
    freopen("job.out","w",stdout);
    cin >> n;
    for (int i = 1; i <= n; i ++)
        scanf("%d %d",&a[i].d,&a[i].p);
    a[++n].d = 0;a[n].p = 0;
    sort(a + 1,a + n +1);
    long long ans = 0;
    long long now = 1000000000;
    for (int i = n; i > 0; i--)
    {
        while (now > a[i].d && q.size() > 0)
        {
            now--;
            ans += q.top();
            q.pop();
        }
        now = a[i].d;
        q.push(a[i].p);
    }
    cout << ans << endl;
    fclose(stdin);fclose(stdout);
}

转载于:https://www.cnblogs.com/N-C-Derek/archive/2012/07/11/usaco_09_open_job.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值