ARC121D 1 or 2

ARC121D 1 or 2

诈骗题。

思路

吃一个糖的操作可以看做是和一个 ai 为 0 的糖一起吃。

可以枚举有多少个糖单独吃来确定要增加多少个 0。

问题变为每次吃两颗糖。

根据人类直觉,有一个贪心,最小的糖和最大的糖一起吃最优,次小的糖和次大的糖一起吃最优,依次类推。

怎么证明这个性质呢?

有 2 个理解方法:

感性理解:

使最大值最小,那么最大的数肯定加上最小的数最优;最小值最大,那么最小的数加上最大的数最优;应该可以理解以上结论。

理性理解:

A<B<C<D

可以选 A+D,B+C,同时也可以选 A+C,B+D。(A+B,C+D 肯定不优,故不考虑)

|(A+D)(B+C)||(A+C)(B+D)|

|(A+D)(B+C)|=|AB+DC|

|(A+C)(B+D)|=|AB+CD|

T=AB

T<0

所以,

|AB+DC|=|T+(DC)|

|AB+CD|=|T+(CD)|

由于 |DC|=|CD|,且 DC>0CD<0

结合 T<0,有 |T+(CD)|>|T+(DC)|

排序后 将 0 加入 a 数组,然后塞到队列里就 OK,每次取队头队尾。

CODE

#include<bits/stdc++.h>
using namespace std;

#define ll long long

const ll maxn=6e3;

ll n;

ll ans;
ll a[maxn];

deque<ll>que;

int main()
{
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
    sort(a+1,a+n+1);

    ans=1e18;
    for(ll k=0;k<=n;k++)
    {
        ll tmp=k,has=n+k;
        ll mx=-1e18,mi=1e18;
        for(ll i=1;i<=n;i++)
        {
            if(a[i]>0)
                while(tmp) que.push_back(0),tmp--;
            que.push_back(a[i]);
        }
        while(tmp) que.push_back(0),tmp--;
        while(has>1)
        {
            has-=2;
            ll v=que.front()+que.back();
            que.pop_front();
            que.pop_back();
            mx=max(v,mx);
            mi=min(v,mi);
        }
        if(has) mi=min(mi,que.front()),mx=max(mx,que.front()),que.pop_back();
        ans=min(ans,mx-mi);
    }

    printf("%lld",ans);
}

代码比较抽象,看看就好。

posted @   彬彬冰激凌  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示