kkio。|

_kkio

园龄:1年7个月粉丝:6关注:1

[CF335F] Buy One,Get One Free

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

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

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

甚至可以简化到只用一层反悔,具体就是第一层可以简化到只记数量,第三层分析出可以归成第二层的形式。

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

本文作者:_kkio

本文链接:https://www.cnblogs.com/hikkio/p/17792142.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   _kkio  阅读(16)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起