• [USACO]工作调度


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

    作者: witliu 更新时间: 2017-07-22 10:10  在Ta的博客查看  5 


    贪心思想:先假设每一项工作都做,将各项工作按截止时间排序后入队,在判断第i项工作做与不做时,若其截至时间符合条件,则将其与队中报酬最小的元素比较,若第i项工作报酬较高,则ans+=a[i].p-q.top()。用优先队列(小根堆)来维护队首元素最小。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<queue>
     5 using namespace std;
     6 typedef long long ll;
     7 const int maxn=1e6+7;
     8 ll n,ans;
     9 struct Node{
    10   ll d,p;
    11 }node[maxn];
    12 priority_queue<ll,vector<ll>,greater<ll> >q;
    13 bool cmp(Node a,Node b){
    14   return a.d<b.d;
    15 }
    16 int main(){
    17   cin>>n;
    18   for(ll i=1;i<=n;i++) cin>>node[i].d>>node[i].p;
    19   sort(node+1,node+n+1,cmp);
    20   for(ll i=1;i<=n;i++){
    21     if(node[i].d>q.size()){
    22       ans+=node[i].p;q.push(node[i].p);
    23     }
    24     else{
    25       if(node[i].p>q.top()){
    26         ans+=node[i].p-q.top();q.pop();q.push(node[i].p); 
    27       }
    28     }
    29   }
    30   cout<<ans<<endl;
    31   return 0;
    32 } 
  • 相关阅读:
    Atitit. 衡量项目规模 包含的类的数量 .net java类库包含多少类 多少个api方法??
    Drawable 中getIntrinsicWidth
    js播放音乐
    Parcelable和Parcel
    标题栏和状态栏
    android振动效果的实现
    Android位置服务和Google地图API初解
    TranslateAnimation详解
    android真机调试
    常见的Android图标大小
  • 原文地址:https://www.cnblogs.com/lcan/p/9692293.html
Copyright © 2020-2023  润新知