题意:
n个人(1,2,…n),围成圈站(即第一个人左边是最后一个人),每个人有一定金币数,可将金币转移左右相邻的人,合理分配使得每个人的金币数相同,求分配过程中需转移金币的最小值。
思路:
1 给 2 x2 个金币
2 给 3 x3 个金币
k 给 k+1 k+1个金币
n 给 1 x1 个金币
Aver = a1 - x2 + x1 -> x2 = aver -a1 + x1
Aver = a2 - x3 + x2 -> x3 = aver -a2 + x2
Aver = a3 - x4 + x3 -> x4 = aver -a3 + x3
Aver = a4 - x5 + x4 -> x5 = aver -a4 + x4
……
ci为∑aj- Aver
cnt = |x1|+|x2|+|x3|+…+|xn|=|x1 - 0| + |x1 - c1| + |x1 - c2|+...+|x1- cn-1|
则该问题即为 求x1使得 x1到这些点的距离之和最小 模型
-> 即求ci的中位数
代码:
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
long long arr[1000005],temp[1000005];
int main() {
int n;
while (scanf("%d", &n)==1) {
int i;
long long sum=0,t, cnt=0, aver;
for (i = 1; i <= n; i++){
scanf("%lld",&arr[i]);
sum += arr[i];
}
aver = sum / n;
temp[0] = 0;
for (i = 1; i < n; i++){
temp[i] = temp[i - 1] + aver - arr[i+1];
}
sort(temp,temp+n);
t = temp[n/2];
for (i = 0; i < n; i++){
cnt += abs(t - temp[i]);
}
printf("%lld\n",cnt );
}
}