AtCoder Beginner Contest 137 D - Summer Vacation——————贪心,优先队列

D - Summer Vacation


Time Limit: 2 sec / Memory Limit: 1024 MB

Score : 400400 points

Problem Statement

There are NN one-off jobs available. If you take the ii-th job and complete it, you will earn the reward of BiBi after AiAi days from the day you do it.

You can take and complete at most one of these jobs in a day.

However, you cannot retake a job that you have already done.

Find the maximum total reward that you can earn no later than MM days from today.

You can already start working today.

Constraints

  • All values in input are integers.
  • 1≤N≤1051≤N≤105
  • 1≤M≤1051≤M≤105
  • 1≤Ai≤1051≤Ai≤105
  • 1≤Bi≤1041≤Bi≤104

Input

Input is given from Standard Input in the following format:

NN MM
A1A1 B1B1
A2A2 B2B2
⋮⋮
ANAN BNBN

Output

Print the maximum total reward that you can earn no later than MM days from today.


Sample Input 1 Copy

Copy

3 4
4 3
4 1
2 2

Sample Output 1 Copy

Copy

5

You can earn the total reward of 55 by taking the jobs as follows:

  • Take and complete the first job today. You will earn the reward of 33 after four days from today.
  • Take and complete the third job tomorrow. You will earn the reward of 22 after two days from tomorrow, that is, after three days from today.

Sample Input 2 Copy

Copy

5 3
1 2
1 3
1 4
2 1
2 3

Sample Output 2 Copy

Copy

10

Sample Input 3 Copy

Copy

1 1
2 1

Sample Output 3 Copy

Copy

0

每天只能领取一个工作,不过每天可以做的工作可以有多个
比如样例111,第一天领取4 34\ 34 3,在第四天可以得到3的奖励,第二天领取2 22\ 22 2,第三天可以获得2的奖励

我们可以知道,在第iii天,不能领取工作时长超过m−i+1m-i+1m−i+1的工作,于是我们就可以在这些满足条件的工作中选择奖励最高的。
倒着想就行了,在倒数第iii天,我能选择的工作是:工作时长不超过iii的,在这些满足条件的工作中选择奖励最高的。
用个优先队列维护一下,不过得先排序,按照天数递增排序

贪心,思维,优先队列
 

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5+7;
typedef long long ll;

struct node{
        ll a,b;
}z[MAXN];

bool cmp(node x,node y) {
        return x.a<y.a;
}

int main() {
        int n,m;
        while(cin>>n>>m) {
                for(int i=0;i<n;++i)
                        cin>>z[i].a>>z[i].b;
                sort(z,z+n,cmp);
                ll ans = 0;
                int id = 0;
                priority_queue<ll> que;
                for(int i=1;i<=m;++i) {
                        while(z[id].a<=i && id<n) {
                                que.push(z[id].b);
                                id++;
                        }
                        if(que.empty()) continue;
                        ans += que.top();
                        que.pop();
                }
                cout<<ans<<endl;
        }
        return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值