abc137_D - Summer Vacation
Problem Statement
There are one-off jobs available. If you take the i-th job and complete it, you will earn the reward of after 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 days from today.
You can already start working today.
Constraints
All values in input are integers.
Input
Input is given from Standard Input in the following format:
Output
Print the maximum total reward that you can earn no later than 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 by taking the jobs as follows:
- Take and complete the first job today. You will earn the reward of after four days from today.
- Take and complete the third job tomorrow. You will earn the reward of 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
每天只能領取一個工作,不過每天可以做的工作可以有多個
比如樣例,第一天領取,在第四天可以得到3的獎勵,第二天領取,第三天可以獲得2的獎勵
我們可以知道,在第天,不能領取工作時長超過的工作,於是我們就可以在這些滿足條件的工作中選擇獎勵最高的。
倒着想就行了,在倒數第天,我能選擇的工作是:工作時長不超過的,在這些滿足條件的工作中選擇獎勵最高的。
用個優先隊列維護一下,不過得先排序,按照天數遞增排序
貪心,思維,優先隊列
#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;
}