题目链接:https://vjudge.net/contest/132704#problem/C
题意:圆桌上每个人有一定的金币,左右互传,使得每人的金币相同,求最少需要移动的金币。
分析:
状态的定义: xi 为 i 向 i-1移动了多少,则有 Ai - xi + xi-1 = m(平均数)
依次类推:
x1
x2 = x1 - (Ai-1 的前缀和 - (i-1)*m);
那么就是求|x1| + |x1-Ci-1| + |x1 - Ci-1| 的和最小。
就类似于数组的点,x1与各点之和最小,x1的位置就是中位数。

1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1000000 + 5; 6 7 long long A[maxn]; 8 long long C[maxn]; 9 10 int main() 11 { 12 13 int n; 14 while(scanf("%d",&n)!=EOF) { 15 long long sum = 0; 16 for(int i=0;i<n;i++) { 17 scanf("%lld",&A[i]); 18 sum +=A[i]; 19 } 20 21 long long M = sum/n; 22 23 C[0] = 0; 24 for(int i=1;i<n;i++) 25 C[i] = C[i-1] + A[i] - M; 26 27 sort(C,C+n); 28 long long x1 = C[n/2],ans = 0; 29 for(int i=0;i<n;i++) 30 ans+=abs(x1-C[i]); 31 32 cout<<ans<<endl; 33 34 } 35 36 return 0; 37 }