恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
#include <algorithm>#include <cmath>#include <cstring>#include <iostream>#include <queue>using namespace std;struct f { long long d; long long p;} a[100005];bool cmp(f A, f B) { return A.d < B.d; }// 小根堆维护最小值priority_queue<long long, vector<long long>, greater<long long>> q;int main() { long long n, i; cin >> n; for (i = 1; i <= n; i++) { cin >> a[i].d >> a[i].p; } sort(a + 1, a + n + 1, cmp); long long ans = 0; for (i = 1; i <= n; i++) { if (a[i].d <= (int)q.size()) { // 超过截止时间 if (q.top() < a[i].p) { // 后悔 ans += a[i].p - q.top(); q.pop(); q.push(a[i].p); } } else { // 直接加入队列 ans += a[i].p; q.push(a[i].p); } } cout << ans << endl; return 0;}
Python
from collections import defaultdictfrom heapq import heappush, heappopa = defaultdict(list)for _ in range(int(input())): d, p = map(int, input().split()) a[d].append(p) # 存放对应时间的收益ans = 0 # 记录总收益q = [] # 小根堆维护最小值l = sorted(a.keys(), reverse=True)for i, j in zip(l, l[1:] + [0]): for k in a.pop(i): heappush(q, ~k) for _ in range(i - j): if q: # 从堆中取出收益最多的工作 ans += ~heappop(q) else: # 堆为空时退出循环 breakprint(ans)
[!note]- 复杂度分析
空间复杂度:当输入 n 个任务时使用 n 个 a 数组元素,优先队列中最差情况下会储存 n 个元素,则空间复杂度为 O(n)。