作業スケジューリングG
トピックリンク:ybt高効率アドバンスト4-1-4 / luogu P2949
一般的なアイデア
期限があり、価値のあるタスクがいくつかあります。
次に、完了していないタスクをすべての時点で期限内に完了し、このタスクの値を取得できます。
あなたに最大の価値を尋ねてください。
アイデア
タイムラインに従うのは難しいので、後戻りすることを検討します。
締め切り前にできるので、時間が経つにつれて、ますます多くのタスクを実行できることがわかります。
それぞれの瞬間に、私たちが実行できるいくつかのタスクがあります。どれを選択する必要がありますか?
はい、それは最も価値のあるものを選ぶことです。あなたが今できる仕事はいつもそれをすることなので、この欲は正しいです。
ヒープを使用して最大値を維持できます。
そうすれば、アイテムを使用して時間を進めるたびに(1つずつ列挙時間ではなく、タイムアウトになります)、それを処理することができます。
コード
#include<queue>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
struct node {
ll d, p;
}a[100001];
ll n, now, ans;
priority_queue <ll> q;
bool cmp(node x, node y) {
return x.d > y.d;
}
int main() {
scanf("%lld", &n);
for (ll i = 1; i <= n; i++) scanf("%lld %lld", &a[i].d, &a[i].p);
sort(a + 1, a + n + 1, cmp);
now = 1e9;
for (ll i = 1; i <= n; i++) {
if (now == a[i].d) q.push(a[i].p);//同一个时间,放进去
else {
//在不同的时间,可以有时间完成后面累积下来的
ll num = now - a[i].d;
while (num--) {
//做完了后面所有的任务
if (q.empty()) break;
ans += q.top();
q.pop();
}
now = a[i].d;
q.push(a[i].p);
}
}
while (now--) {
//处理一开始的
if (q.empty()) break;
ans += q.top();
q.pop();
}
printf("%lld", ans);
return 0;
}