题解:P14374 [JOISC 2018] 糖果 / Candies
Solution
对于这道题,考虑反悔贪心。
为什么是反悔贪心?
普通贪心每次选当前单颗糖的最大美味值
反悔策略
选出
用链表维护当前节点左右两边、优先队列维护最大值即可。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5;
int n, tot, a[N], lt[N], rt[N];
bool vis[N];
struct Node {
int val, idx;
bool operator < (const Node &nxt) const {
return val < nxt.val;
}
};
priority_queue<Node> q;
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n;
a[0] = a[n + 1] = -1e18;
for (int i = 1; i <= n; i++) {
cin >> a[i];
lt[i] = i - 1;
rt[i] = i + 1;
q.push({a[i], i});
}
int ans = 0;
for (int i = 1; i <= ((n + 1) >> 1); i++) {
while (!q.empty() && vis[q.top().idx])
q.pop();
auto [val, idx] = q.top();
q.pop();
ans += a[idx];
cout << ans << '\n';
a[idx] = a[lt[idx]] + a[rt[idx]] - a[idx];
int l = lt[idx];
rt[lt[l]] = rt[l];
lt[rt[l]] = lt[l];
vis[l] = 1;
int r = rt[idx];
rt[lt[r]] = rt[r];
lt[rt[r]] = lt[r];
vis[r] = 1;
q.push({a[idx], idx});
}
return 0;
}