设 xi表示第i堆给i-1堆xi个金币(x1表示第一堆给第N堆)
设Ai表示原来每堆的数量,M为平均数
那么
A1 - x1 + x2 = M -〉 x2 = M - A1 + x1 = x1 - C1 ( C1 = A1 - M )
A2 - x2 + x3 = M -〉 x3 = M - A2 + x2 = x1 - C2 ( C2 = A1 + A2 - M * 2 )
A3 - x3 + x4 = M -〉 x4 = M - A3 + x3 = x1 - C3 ( C3 = A1 + A2 + A3 - M * 3 )
.......
An-1 - xn-1 + xn = M -〉 xn = M - An-1 + xn-1 = x1 - Cn-1 ( Cn-1 = A1 + A2 + A3 + ...+ An-1 - M * ( n - 1 ) )
那么这题就是求 f = | x1 | + | x2 | + ...+ | xn | 的最小值
也就是求 f = | x1 | + | x1 - C1 | + | x1 - C2 |...+ | x1 - Cn-1 | 的最小值
那么取x1 为 0,C1,......Cn-1的中位数即可
AC代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
long long num[1100001];
long long sum, C[1100001];
int N;
long long ans;
int main(){
while( scanf( "%d", &N ) != EOF ){
sum = 0;
C[0] = 0;
for( int i = 1; i <= N; i++ ){
scanf( "%lld", &num[i] );
C[i] = C[i-1] + num[i];
sum += num[i];
}
for( int i = 1; i < N; i++ ){
C[i] -= sum / N * i;
}
sort( C, C + N );
ans = 0;
for( int i = 0; i < N; i++ ){
ans += abs( C[N/2] - C[i] );
}
printf( "%lld\n", ans );
}
}