【题解】arc189_b Minimize Sum

arc189_b Minimize Sum

题意

给定长度为 \(n\) 的递增序列 \(a\),每次可以选择一个下标 \(i(i+3\le n)\) 进行操作:

  • \(a_{i+1}\)\(a_{i+2}\) 分别以 \(a_i\)\(a_{i+3}\) 的中点为对称点作对称变换。

求通过不限次操作后得到的 \(\displaystyle \sum_{i=1}^n a_i\) 的最小值。

题解

知识点:差分,贪心。

需要观察力的一道题。

\(A,B,C,D\) 分别为序列中四个相邻的数,且值分别为 \(a,b,c,d(a<b<c<d)\)

\(A\)\(D\) 的中点为 \(\frac{a+d}{2}\)

\(B\)\(C\) 作对称变换后值变为 \(a+d-c\)\(a+d-b\)

现在 \(A,B,C,D\) 值分别为 \(a,a+d-c,a+d-b,d\)

在这个时候,如果你想到去作差分,那么你会发现原来 \(A,B,C,D\) 差分序列为 \(a,b-a,c-b,d-c\),变换后差分序列为 \(a,d-c,c-b,b-a\),在差分序列上就相当于交换了 \(B,D\)

果断将原序列也作差分得到 \(d_i=a_i-a_{i-1}\),那么变为最小化 \(\displaystyle \sum_{i=1}^n \sum_{j=1}^i d_j\),显然更小的 \(d_i\) 被换到前面会让这个式子的值变小。

但交换不是能随便交换,发现除了 \(d_1\) 不能动(能参与交换的数下标至少为 \(2\))以外,下标奇偶性相同的 \(d_i\) 之间可以随便交换,故考虑对奇偶分别贪心。

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

#define rep(i,l,r) for(int i=(l);i<=(r);++i)
#define per(i,l,r) for(int i=(r);i>=(l);--i)
#define pr pair<int,int>
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define bg(x) (x).begin()
#define ed(x) (x).end()

#define N 202507
#define int long long

int n,a[N];
vector<int>v[2];

signed main(){
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    cin>>n;
    
    rep(i,1,n){
        cin>>a[i];
    }

    per(i,1,n){
        a[i]-=a[i-1];

        if(i>=2){
            v[i%2].pb(a[i]);
        }
    }

    sort(all(v[0]));
    sort(all(v[1]));

    rep(i,0,sz(v[0])-1){
        a[(i+1)*2]=v[0][i];
    }

    rep(i,0,sz(v[1])-1){
        a[(i+1)*2+1]=v[1][i];
    }

    int ans=0;

    rep(i,1,n){
        a[i]+=a[i-1];
        ans+=a[i];
    }

    cout<<ans;

    return 0;
}
posted @ 2025-07-10 20:54  Lucyna_Kushinada  阅读(16)  评论(0)    收藏  举报