zoukankan      html  css  js  c++  java
  • 【bzoj1572】[Usaco2009 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位整型。

    输入

    第1行:一个整数N. 第2~N+1行:第i+1行有两个用空格分开的整数:D_i和P_i.

    输出

    输出一行,里面有一个整数,表示最大获利值。

    样例输入

    3
    2 10
    1 5
    1 7

    样例输出

    17


    题解

    贪心

    原本以为是按照p从大到小排序,结果发现这样做的话代码没法写。

    于是改变策略,按d从小到大排序。

    每次找到一个工作以后,看时间能否满足。

    如果能,就选它,把它加到小根堆中,并把时间+1.

    若不能,就看堆中最小元素是否比p要小,如果是,则删除那个元素,再添加当前元素。

    由于priority_queue默认是大根堆,所以我把p取相反数后再加进堆中,就变成小根堆了。

    #include <cstdio>
    #include <queue>
    #include <algorithm>
    using namespace std;
    typedef long long lint;
    struct data
    {
    	int d;
    	lint p;
    }a[100010];
    priority_queue<lint> q;
    bool cmp(data a , data b)
    {
    	return a.d < b.d;
    }
    int main()
    {
    	int n , i , now = 0;
    	lint x , ans = 0;
    	scanf("%d" , &n);
    	for(i = 1 ; i <= n ; i ++ )
    		scanf("%d%lld" , &a[i].d , &a[i].p);
    	sort(a + 1 , a + n + 1 , cmp);
    	for(i = 1 ; i <= n ; i ++ )
    	{
    		if(now < a[i].d)
    			q.push(-a[i].p) , ans += a[i].p , now ++ ;
    		else
    		{
    			x = -q.top();
    			if(x < a[i].p)
    			{
    				q.pop();
    				ans -= x;
    				q.push(-a[i].p);
    				ans += a[i].p;
    			}
    		}
    	}
    	printf("%lld
    " , ans);
    	return 0;
    }

     

  • 相关阅读:
    c_水程序
    Arlenmbx!!!!
    java
    c语言随机函数&&时间函数
    2016省赛总结
    666
    【UOJ#389】【UNR#3】白鸽(欧拉回路,费用流)
    【洛谷P3756】[CQOI2017]老C的方块(最小割)
    CF704D Captain America(上下界网络流)
    AtCoder Regular Contest 097
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6412550.html
Copyright © 2011-2022 走看看