洛谷P2949 [USACO09OPEN]Work Scheduling G

题目链接:https://www.luogu.com.cn/problem/P2949

题目描述

Farmer John has so very many jobs to do! In order to run the farm efficiently, he must make money on the jobs he does, each one of which takes just one time unit.

His work day starts at time 0 and has 1,000,000,000 time units (!). He currently can choose from any of N (1 <= N <= 100,000) jobs

conveniently numbered 1..N for work to do. It is possible but

extremely unlikely that he has time for all N jobs since he can only work on one job during any time unit and the deadlines tend to fall so that he can not perform all the tasks.

Job i has deadline D_i (1 <= D_i <= 1,000,000,000). If he finishes job i by then, he makes a profit of P_i (1 <= P_i <= 1,000,000,000).

What is the maximum total profit that FJ can earn from a given list of jobs and deadlines? The answer might not fit into a 32-bit integer.

输入格式

* 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.

题意翻译

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

输入输出样例

输入 #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).

这是一道贪心题目,先将数据按照截止日期从大到小排序,记录最大的截止日期,然后让i从这个最大截止日期到1循环,每次循环就是让截止日期是i的工作加入堆中,然后从堆中弹出最大值,让这一个单位时间完成这个工作,可以让利润最大。

要注意的是:如果堆为空,则应让i跳到下一个工作的日期,否则会TLE第二个点。

代码:

#include<stdio.h>
struct node{
    int v,t;
}s[10000001],a[10000001],pk[10000001],q;
int lena,n,maxt,lens;long long ansa;
int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
void px(int l,int r){
    if(l==r)return;
    int i=l,k=l,j,mid=(l+r)/2;j=mid+1;
    px(l,mid);px(mid+1,r);
    while(i<=mid&&j<=r)
        if(s[i].t>s[j].t)pk[k++]=s[i++];
        else pk[k++]=s[j++];
    while(i<=mid)pk[k++]=s[i++];
    while(j<=r)pk[k++]=s[j++];
    for(i=l;i<=r;i++)s[i]=pk[i];
    return;
}
void puta(struct node res){
    int now,next;struct node p;
    a[++lena]=res;
    now=lena;
    while(now>1){
        next=now>>1;
        if(a[now].v<=a[next].v)break;
        p=a[now];a[now]=a[next];a[next]=p;
        now=next;
    }
    return;
}
struct node geta(){
    int now,next;struct node res,p;
    if(lena==0)return (struct node){-1,-1};
    res=a[1];
    a[1]=a[lena--];
    now=1;
    while((now<<1)<=lena){
        next=now<<1;
        if(next<lena&&a[next+1].v>a[next].v)next++;
        if(a[now].v>=a[next].v)break;
        p=a[now];a[now]=a[next];a[next]=p;
        now=next;
    }
    return res;
}
int main(){
    n=read();
    for(int i=1;i<=n;i++)s[i].t=read(),s[i].v=read();
    maxt=0;
    for(int i=1;i<=n;i++)if(s[i].t>maxt)maxt=s[i].t;
    px(1,n);
    lena=0;lens=1;ansa=0;
    for(int i=maxt;i>=1;i--){
        while(lens<=n&&s[lens].t==i)puta(s[lens++]);
        q=geta();
        if(q.t!=-1&&q.v!=-1)ansa+=q.v;
        else i=s[lens].t+1;
    }
    printf("%lld",ansa);
    return 0;
}
原文地址:https://www.cnblogs.com/sy666/p/12815398.html