[CF335F] Buy One,Get One Free

发布时间 2023-10-27 13:28:05作者: _kkio

气死我了,我决定水了这篇题解。

反悔贪心,考虑决策及反悔,记到第三层反悔就行。

然后你发现要一次只考虑一个不行,要两个两个考虑,然后就做完了,如果深入往下分析能分析出更多可以简化做法的结论。

#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';
}