题目
题目描述
有 n n n个小朋友坐成一圈,每人有 a i a_{i} ai颗糖果。每个人只能给左右两人传递糖果。每人每次传递一颗糖果的代价为1。求使所有人获得均等糖果的最小代价。
输入格式
第一行有一个整数 n n n,表示小朋友的个数。
在接下来 n n n行中,每行一个整数 a i a_{i} ai。
样例
输入
输出
数据范围与提示
对于 30 % 30\% 30%的数据,n$ \leqslant$ 1000
对 100 % 100\% 100%的数据,n ⩽ 1 0 6 \leqslant 10^6 ⩽106,保证答案可以用64位有符号整数储存
分析
设 x i x_{i} xi表示第 i i i个小朋友向第 i − 1 i-1 i−1个小朋友传递了多少颗糖果, s u m sum sum表示均等糖果的值。
那么可以分析出式子: a i − x i + x i + 1 = s u m a_{i}-x_{i}+x_{i+1}=sum ai−xi+xi+1=sum 即: x i − x i + 1 = a i − s u m x_{i}-x_{i+1}=a_{i}-sum xi−xi+1=ai−sum
同理:
x 1 − x 2 = a 1 − s u m x_{1}-x_{2}=a_{1}-sum x1−x2=a1−sum
x 2 − x 3 = a 2 − s u m x_{2}-x_{3}=a_{2}-sum x2−x3=a2−sum
x 3 − x 4 = a 3 − s u m x_{3}-x_{4}=a_{3}-sum x3−x4=a3−sum
………………
x n − 1 − x n = a n − 1 − s u m x_{n-1}-x_{n}=a_{n-1}-sum xn−1−xn=an−1−sum
共 n − 1 n-1 n−1个式子。
前 n − 1 n-1 n−1个式子相加
x 1 − x n = ∑ i = 1 n − 1 a i − ( n − 1 ) s u m x_{1}-x_{n}= \sum_{i=1}^{n-1} a_i-(n-1)sum x1−xn=∑i=1n−1ai−(n−1)sum
设 t i t_{i} ti表示常量
那么 x 1 = t n − 1 + x n x_{1}=t_{n-1}+x_{n} x1=tn−1+xn
前 n − 2 n-2 n−2个式子相加
x 1 − x n − 1 = ∑ i = 1 n − 2 a i − ( n − 2 ) s u m x_{1}-x_{n-1}= \sum_{i=1}^{n-2} a_i-(n-2)sum x1−xn−1=∑i=1n−2ai−(n−2)sum
x 1 = t n − 2 + x n − 1 x_{1}=t_{n-2}+x_{n-1} x1=tn−2+xn−1
前 n − 3 n-3 n−3个式子相加
x 1 − x n − 2 = ∑ i = 1 n − 3 a i − ( n − 3 ) s u m x_{1}-x_{n-2}=\sum_{i=1}^{n-3}a_{i}-(n-3)sum x1−xn−2=∑i=1n−3ai−(n−3)sum
x 1 = t n − 3 + x n − 2 x_{1}=t_{n-3}+x_{n-2} x1=tn−3+xn−2
………………
前 2 2 2个式子相加
x 1 − x 3 = ∑ i = 1 2 a i − s u m x_{1}-x{3}=\sum_{i=1}^{2}a_{i}-sum x1−x3=∑i=12ai−sum
x 1 = t 2 + x 3 x_{1}=t_{2}+x_{3} x1=t2+x3
前 1 1 1个式子
x 1 = t 1 + x 2 x_{1}=t_{1}+x_{2} x1=t1+x2
答案 a n s ans ans为 ∣ x 1 ∣ + ∣ x 2 ∣ + … … + ∣ x n − 1 ∣ + ∣ x n ∣ |x_{1}|+|x_{2}|+……+|x_{n-1}|+|x_{n}| ∣x1∣+∣x2∣+……+∣xn−1∣+∣xn∣
即为: ∣ x 1 + t n ∣ + ∣ x 1 − t 1 ∣ + ∣ x 1 − t 2 ∣ + … … … … + ∣ x 1 − t n − 2 ∣ + ∣ x 1 − t n − 1 ∣ |x_{1}+t_{n}|+|x_{1}-t_{1}|+|x_{1}-t{2}|+…………+|x_{1}-t_{n-2}|+|x_{1}-t_{n-1}| ∣x1+tn∣+∣x1−t1∣+∣x1−t2∣+…………+∣x1−tn−2∣+∣x1−tn−1∣
问题转换为了在一条线上有 n n n个点,求一个点到其他点的距离和最小(即为 x 1 x_{1} x1的值
所以 x 1 为 x_{1}为 x1为t_{1} 到 到 到t_{n-1}$的中位数
Code
#include<bits/stdc++.h>
#define maxn 1000001
#define ll long long
using namespace std;
ll n;
ll a[maxn];
ll cnt;
ll ans;
ll sum[maxn];
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
cnt+=a[i];
}
cnt/=n;//平均值
for(int i=1;i<=n;i++){
a[i]-=cnt;
sum[i]=sum[i-1]+a[i];
}
sort(sum+1,sum+n+1);
int k=sum[n+1>>1];//中位数
for(int i=1;i<=n;i++){
ans+=abs(sum[i]-k);
}
printf("%lld",ans);
return 0;
}