ABC137 D問題 Summer Vacation
問題文
件の日雇いアルバイトがあり、 件目の日雇いアルバイトを請けて働くと、その 日後に報酬 が得られます。
あなたは、これらの中から 日に 件まで選んで請け、働くことができます。
ただし、請けたことのある日雇いアルバイトは選べません。
今日から 日後まで( 日後を含む)に得られる報酬の合計の最大値を求めてください。
なお、日雇いアルバイトは今日から請けて働くことができます。
制約
- 入力は全て整数である。
解法の方針
- 最終日から数えていき、できるようになった仕事を集合に追加する
- 集合にはprioriuty_queueを用いる
注意点
- 最終日から遡る必要がある
解答例
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define rep(i, n) for (int i = 0; i < (n); ++i) int main(){ int n,m; cin>>n>>m; vector<vector<int>> jobs(m); //何日目に解禁される仕事かを保持するvector rep(i,n){ int a,b; cin>>a>>b; if(a>m) continue; jobs[m-a].push_back(b); //m-a日目に解禁される要素として追加 比較はbでするのでbだけ追加 } priority_queue<int> q; ll ans=0; for(int i=m-1;i>=0;--i){ //m-1日目から遡ってvectorの要素をpriority_queueに移す for(int b : jobs[i]){ q.push(b); } if(!q.empty()){ //空でtop()すると壊れる ans += q.top(); //ansに収入を足す q.pop(); //やった仕事は消す } } cout<<ans<<endl; }
学んだこと
- 逆順に見ていく
- 貪欲法
- priority_queue
.push()で要素を追加し、.top()で取り出すと、大きいものから順に出てくるコンテナ
知らなかったのでいちいちソートするのか?と思っていたが、これを使うとO(logN)でできるらしい