将序列变成等差的最小代价——2019CTU F

这题解决了我一直以来不明白的一个模型,就是将序列变成等差的最小代价

题库链接

https://www.jisuanke.com/contest/7652?view=challenges

2020 campday7 的I也是这个模型

/*
不妨假设:a[1]一开始就在第一个目标位置,那么整个序列就变成a[i]=a[i]-(i-1)*k
 新的a[i]表示第i个物体需要移动多少距离(矢量)能到指定的位置
 其实这个模型等价于 给定一串点,要求找到一个点,使所有点到达这个点的距离和最小
 (在这题的模型中的参照点等价于那个所有点最后到达的点) 
 那么其实就是找中位数 
*/
#include <iostream>
#include <cassert>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long int ll;

int main(){
    ll N,K;
    cin>>N>>K;
    assert(1 <= N && N <= 1000000);
    assert(1 <= K && K <= 1000000);
    vector<ll> a(N);
    for(int i=0; i<N; ++i){
        cin>>a[i];
        assert(-1000000 <= a[i] && a[i] <= 1000000);
    }
    sort(a.begin(),a.end());
    ll dif=0;
    for(int i=0; i<N; ++i){
        a[i]-=dif;
        dif+=K;
    }
    sort(a.begin(),a.end());
    
    ll med=a[N/2];
    ll res=0;
    for(int i=0; i<N; ++i){
        res+=abs(med-a[i]);
    }
    cout<<res<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zsben991126/p/12349254.html
F