解决思路
- 排序:首先将所有工作按照截止时间 D_i 进行排序。
- 优先队列:使用一个最小堆来存储当前选择的工作的利润。
- 选择工作:遍历所有工作,如果当前工作的截止时间大于堆的大小,则将该工作加入堆中;否则,如果当前工作的利润大于堆顶的利润,则替换堆顶的工作。
#include <bits/stdc++.h> #define ll long long #define pii pair<int, int> using namespace std; const int N = 1e5 + 10; // 定义一个结构体来存储每个工作的截止时间和利润 struct node { int t, x; }; // 定义一个数组来存储所有的工作 node a[N]; int n; // 比较函数,用于按照截止时间对工作进行排序 bool cmp(node a, node b) { return a.t < b.t; } int main() { cin >> n; // 读取每个工作的截止时间和利润 for (int i = 1; i <= n; i++) { cin >> a[i].t >> a[i].x; } // 按照截止时间对工作进行排序 sort(a + 1, a + 1 + n, cmp); // 定义一个最小堆,用于存储当前选择的工作的利润 priority_queue<int, vector<int>, greater<int>> q; ll ans = 0; // 遍历所有工作 for (int i = 1; i <= n; i++) { // 如果当前工作的截止时间大于堆的大小,则将该工作加入堆中 if (q.size() < a[i].t) { q.push(a[i].x); ans += a[i].x; } // 否则,如果当前工作的利润大于堆顶的利润,则替换堆顶的工作 else if (q.size() && q.top() < a[i].x) { ans = ans - q.top() + a[i].x; q.pop(); q.push(a[i].x); } } // 输出最大总利润 cout << ans; return 0; }