气死我了,我决定水了这篇题解。
反悔贪心,考虑决策及反悔,记到第三层反悔就行。
然后你发现要一次只考虑一个不行,要两个两个考虑,然后就做完了,如果深入往下分析能分析出更多可以简化做法的结论。
甚至可以简化到只用一层反悔,具体就是第一层可以简化到只记数量,第三层分析出可以归成第二层的形式。
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
typedef long long ll;
const int inf=2e9;
int n,a[maxn];
ll ans;
priority_queue< int,vector<int>,greater<int> > q;
int main()
{
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],ans+=a[i];
sort(a+1,a+1+n);
reverse(a+1,a+1+n);
for(int i=1,j;i<=n;i=j+1)
{
j=i;
while(j<n&&a[j+1]==a[i])j++;
int q1s=i-1-2*q.size(),num=j-i+1;//本质是第一层决策
vector<int> vec;
for(int j=1;j<=min(num,q1s);j++)vec.push_back(a[i]);
num-=min(num,q1s);
for(int j=1;j<=num&&q.size();j++)
{
int x=q.top();
q.pop();
if(x<a[i])
{
vec.push_back(a[i]);
if(j<num)vec.push_back(a[i]),j++;
}
else
{
vec.push_back(x);
if(j<num&&2*a[i]-x>0)vec.push_back(2*a[i]-x),j++;//本质是第三层反悔。
}
}
for(int v:vec)q.push(v);
}
while(q.size())ans-=q.top(),q.pop();
cout<<ans<<'\n';
}
标签:Buy,cout,第三层,int,CF335F,Free,反悔,vec,ans
From: https://www.cnblogs.com/hikkio/p/17792142.html