zoukankan      html  css  js  c++  java
  • P2949 [USACO09OPEN]工作调度Work Scheduling

    题目描述

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

    输入输出格式

    输入格式:

    * Line 1: A single integer: N

    * Lines 2..N+1: Line i+1 contains two space-separated integers: D_i and P_i

    输出格式:

    * Line 1: A single number on a line by itself that is the maximum possible profit FJ can earn.

    输入输出样例

    输入样例#1: 
    3 
    2 10 
    1 5 
    1 7 
    
    输出样例#1: 
    17 
    

    说明

    Complete job 3 (1,7) at time 1 and complete job 1 (2,10) at time 2 to maximize the earnings (7 + 10 -> 17).

    Solution

      这道题我一开始是往DP方向想的,结果尴尬地发现自己不造怎么定义状态... 于是就想贪心水分.

      结果想了一个自己觉得是正解的贪心做法.然后发现只得了33分...

      又调了良久,还是33分.

      然后一看题解,发现题解只不过是把我的思路倒过来. 然后就对了.很显然我还是太菜了.

      这道题的贪心的策略就是:

      先把所有的价值都加进去.然后同步统计一个now统计时间.

      如果当前时间已经超过了实现,那么我们就减掉价值最小的.

      然后这个价值最小的用一个堆就可以维护.

       

     代码

    #include<bits/stdc++.h>
    #define ll long long 
    using namespace std;
    const int maxn=100008;
    struct sj{
        ll d;
        ll p;
    }a[maxn];
    priority_queue <int> q;
    
    ll read()
    {
        char ch=getchar(); ll f=1,w=0;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();}
        return f*w;
    }
    
    bool cmp(sj s,sj j){if(s.d!=j.d)return s.d<j.d;else return s.p<j.p;}
    
    ll ans,maxt,n;
    ll num,maxs[maxn];
    int main()
    {
        n=read();
        for(int i=1;i<=n;i++) a[i].d=read(),a[i].p=read();
        sort(a+1,a+n+1,cmp);
        ll old=0;
        int now=0;
            for(int i=1;i<=n;i++)
        {
            ans+=a[i].p;
            now++;
            q.push(-a[i].p);
            //大根堆转小根堆
            if(now>a[i].d)
            {
                ans+=q.top(),q.pop();now--;
            }
        }
        cout<<ans<<endl;
    }

    然后 这是我的错误贪心:

      for(int i=n;i>=0;i--)
        {
            if(a[i].d!=old) 
            {
                ll tt=old-a[i].d;
                old=a[i].d;
                while(tt!=0)
                {
                    int t=q.top();
                    q.pop();
                    ans+=a[t].p;        
                    tt--;
                }
            }
            q.push(i);
        }
  • 相关阅读:
    day30 python类的继承,抽象类等
    20170702-变量说明,静态方法,类方法区别,断点调试,fork,yield协程,进程,动态添加属性等。。
    day29 面向对象入门
    day28 import,from * import *,__name__
    day27 模块:正则re, configparser, subprocess
    day26 re正则表达式
    MD5的学习与练习
    HBase
    Struts13---Ognl
    Struts12---文件的下载
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/8857600.html
Copyright © 2011-2022 走看看