题解:P14374 [JOISC 2018] 糖果 / Candies
分析
这种长得很像 dp 但是复杂度显然有问题的题应当考虑贪心。但是发现正常贪心不行,所以考虑反悔贪心。
对于反悔操作,考虑原本选了
发现一个点,选了
另外使用链表还可以避免反悔一次找不回来的情况,因为在原位置插入“反悔操作”实际上允许了反悔之前的反悔操作,反悔反悔之前的反悔操作……所以每一次选择其实都是可以考虑到所有情况的。
每次选择要么直接选一个出来,要么反悔一个选两个出来,必定多选一颗糖,所以选
AC Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int l[N],r[N],vis[N],a[N];
inline void del(int x)
{
r[l[x]]=r[x];
l[r[x]]=l[x];
vis[x]=1;
}
signed main()
{
int n;
cin>>n;
a[0]=a[n+1]=-1e18;
for(int i=1;i<=n;i++) cin>>a[i],l[i]=i-1,r[i]=i+1;
r[n+1]=n+1;
priority_queue<pair<int,int>> q;
for(int i=1;i<=n;i++) q.push({a[i],i});
int ans=0,cnt=0;
while(cnt<(n+1)/2)
{
auto [w,x]=q.top();
q.pop();
if(vis[x]) continue;
cnt++;
ans+=w;
cout<<ans<<'\n';
a[x]=a[l[x]]+a[r[x]]-a[x];
if(l[x]>=1&&r[x]<=n) q.push({a[x],x});
del(l[x]);del(r[x]);
}
}