AtCoder Beginner Contest 137 D - Summer Vacation——————貪心,優先隊列

abc137_D - Summer Vacation

Problem Statement
There are NN one-off jobs available. If you take the i-th job and complete it, you will earn the reward of BiB_i after AiA_i 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.

  • 1N1051≤N≤10^5
  • 1M1051≤M≤10^5
  • 1Ai1051≤A_i≤10^5
  • 1Bi1041≤B_i≤10^4

Input
Input is given from Standard Input in the following format:

NN MM
A1A_1 B1B_1
A2A_2 B2B_2

ANA_N BNB_N

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

Sample Input 1
3 4
4 3
4 1
2 2
Sample Output 1
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
5 3
1 2
1 3
1 4
2 1
2 3
Sample Output 2
10
Sample Input 3
1 1
2 1
Sample Output 3
0


每天只能領取一個工作,不過每天可以做的工作可以有多個
比如樣例11,第一天領取4 34\ 3,在第四天可以得到3的獎勵,第二天領取2 22\ 2,第三天可以獲得2的獎勵

我們可以知道,在第ii天,不能領取工作時長超過mi+1m-i+1的工作,於是我們就可以在這些滿足條件的工作中選擇獎勵最高的。
倒着想就行了,在倒數第ii天,我能選擇的工作是:工作時長不超過ii的,在這些滿足條件的工作中選擇獎勵最高的。
用個優先隊列維護一下,不過得先排序,按照天數遞增排序

貪心,思維,優先隊列

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章