题目链接:https://www.acwing.com/problem/content/124/
题目
有
n
n
n 个小朋友坐成一圈,每人有
a
[
i
]
a[i]
a[i] 个糖果。
每人只能给左右两人传递糖果。
每人每次传递一个糖果代价为 1 1 1。
求使所有人获得均等糖果的最小代价。
输入格式
第一行输入一个正整数
n
n
n,表示小朋友的个数。
接下来 n n n 行,每行一个整数 a [ i ] a[i] a[i],表示第 i i i 个小朋友初始得到的糖果的颗数。
输出格式
输出一个整数,表示最小代价。
数据范围
1
≤
n
≤
1000000
,
1≤n≤1000000,
1≤n≤1000000,
0
≤
a
[
i
]
≤
2
×
1
0
9
,
0≤a[i]≤2×10^9,
0≤a[i]≤2×109,
数据保证一定有解。
输入样例:
4
1
2
5
4
输出样例:
4
思路:
如图所示(代价即交换次数)
假设
x
i
x_i
xi表示
A
i
−
1
A_{i-1}
Ai−1传递到
A
i
A_i
Ai的代价为
x
i
x_i
xi
假设
−
x
i
-x_i
−xi表示
A
i
A_{i}
Ai传递到
A
i
−
1
A_{i-1}
Ai−1的代价为
x
i
x_i
xi
则总代价为
∣
x
1
∣
+
∣
x
2
∣
+
.
.
.
+
∣
x
n
∣
|x_1|+|x_2|+...+|x_n|
∣x1∣+∣x2∣+...+∣xn∣
下面研究每一个位置,平均数为avg
对于
A
1
A_1
A1,有
A
1
−
x
1
+
x
n
=
a
v
g
A_1-x_1+x_n=avg
A1−x1+xn=avg
对于
A
2
A_2
A2,有
A
2
−
x
2
+
x
1
=
a
v
g
A_2-x_2+x_1=avg
A2−x2+x1=avg
对于
A
3
A_3
A3,有
A
3
−
x
3
+
x
2
=
a
v
g
A_3-x_3+x_2=avg
A3−x3+x2=avg
.
.
.
...
...
对于
A
n
−
1
A_{n-1}
An−1,有
A
n
−
1
−
x
n
−
1
+
x
n
−
2
=
a
v
g
A_{n-1}-x_{n-1}+x_{n-2}=avg
An−1−xn−1+xn−2=avg
对于
A
n
A_n
An,有
A
n
−
x
n
+
x
n
−
1
=
a
v
g
A_n-x_n+x_{n-1}=avg
An−xn+xn−1=avg
移项可得
A
1
−
a
v
g
=
x
1
−
x
n
A_1-avg=x_1-x_n
A1−avg=x1−xn
A
2
−
a
v
g
=
x
2
−
x
1
A_2-avg=x_2-x_1
A2−avg=x2−x1
A
3
−
a
v
g
=
x
3
−
x
2
A_3-avg=x_3-x_2
A3−avg=x3−x2
.
.
.
...
...
A
n
−
2
−
a
v
g
=
x
n
−
2
−
x
n
−
3
A_{n-2}-avg=x_{n-2}-x_{n-3}
An−2−avg=xn−2−xn−3
A
n
−
1
−
a
v
g
=
x
n
−
1
−
x
n
−
2
A_{n-1}-avg=x_{n-1}-x_{n-2}
An−1−avg=xn−1−xn−2
A
n
−
a
v
g
=
x
n
−
x
n
−
1
A_n-avg=x_n-x_{n-1}
An−avg=xn−xn−1
把最后两项相加,有
A
n
+
A
n
−
1
−
2
a
v
g
−
x
n
=
−
x
n
−
2
A_n+A_{n-1}-2avg-x_n=-x_{n-2}
An+An−1−2avg−xn=−xn−2
把最后三项相加,有
A
n
+
A
n
−
1
+
A
n
−
2
−
3
a
v
g
−
x
n
=
−
x
n
−
3
A_n+A_{n-1}+A_{n-2}-3avg-x_n=-x_{n-3}
An+An−1+An−2−3avg−xn=−xn−3
则
0
−
x
n
=
−
x
n
0-x_n=-x_n
0−xn=−xn
A
n
−
a
v
g
−
x
n
=
−
x
n
−
1
A_n-avg-x_n=-x_{n-1}
An−avg−xn=−xn−1
A
n
+
A
n
−
1
−
2
a
v
g
−
x
n
=
−
x
n
−
2
A_n+A_{n-1}-2avg-x_n=-x_{n-2}
An+An−1−2avg−xn=−xn−2
A
n
+
A
n
−
1
+
A
n
−
2
−
3
a
v
g
−
x
n
=
−
x
n
−
3
A_n+A_{n-1}+A_{n-2}-3avg-x_n=-x_{n-3}
An+An−1+An−2−3avg−xn=−xn−3
A
n
+
A
n
−
1
+
A
n
−
2
+
A
n
−
3
−
4
a
v
g
−
x
n
=
−
x
n
−
4
A_n+A_{n-1}+A_{n-2}+A_{n-3}-4avg-x_n=-x_{n-4}
An+An−1+An−2+An−3−4avg−xn=−xn−4
.
.
.
...
...
A
n
+
A
n
−
1
+
.
.
.
+
A
2
−
(
n
−
1
)
a
v
g
−
x
n
=
−
x
1
A_n+A_{n-1}+...+A_2-(n-1)avg-x_n=-x_1
An+An−1+...+A2−(n−1)avg−xn=−x1
令
C
1
=
A
n
−
a
v
g
C_1=A_n-avg
C1=An−avg
C
2
=
A
n
+
A
n
−
1
−
2
a
v
g
C_2=A_n+A_{n-1}-2avg
C2=An+An−1−2avg
C
3
=
A
n
+
A
n
−
1
+
A
n
−
2
−
3
a
v
g
C_3=A_n+A_{n-1}+A_{n-2}-3avg
C3=An+An−1+An−2−3avg
.
.
.
...
...
C
n
−
1
=
A
n
+
A
n
−
1
+
.
.
.
+
A
2
−
(
n
−
1
)
a
v
g
C_{n-1}=A_n+A_{n-1}+...+A_2-(n-1)avg
Cn−1=An+An−1+...+A2−(n−1)avg
则总代价可以表示为
∣
C
1
−
x
n
∣
+
∣
C
2
−
x
n
∣
+
∣
C
3
−
x
n
∣
+
.
.
.
+
∣
C
n
−
1
−
x
n
∣
+
∣
x
n
∣
|C_1-x_n|+|C_2-x_n|+|C_3-x_n|+...+|C_{n-1}-x_n|+|x_n|
∣C1−xn∣+∣C2−xn∣+∣C3−xn∣+...+∣Cn−1−xn∣+∣xn∣
由货仓选址可知,取中位数可以使不等式的值最小
另外 C i = C i − 1 + A i − a v g C_i=C_{i-1}+A_i-avg Ci=Ci−1+Ai−avg
AC代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 1000010;
typedef long long LL;
int n;
LL arr[N],c[N];
LL all,avg,ans;
int main()
{
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
scanf("%lld",&arr[i]);
all += arr[i];
}
avg = all / n;
c[0] = 0;
// for(int i = 1; i < n; i++) c[i] = c[i-1] + avg - arr[i];
// 上面这个递推式也行
for(int i = 1; i < n; i++) c[i] = c[i-1] - avg + arr[i];
sort(c,c+n);
avg = c[n/2];
for(int i = 0; i < n; i++) ans += abs(c[i] - avg);
printf("%lld\n",ans);
return 0;
}