//目录

Uva 11300 分金币

题目链接:https://vjudge.net/contest/132704#problem/C

题意:圆桌上每个人有一定的金币,左右互传,使得每人的金币相同,求最少需要移动的金币。

分析:

状态的定义: x为 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 }
View Code

 

posted @ 2017-01-24 22:14  小草的大树梦  阅读(210)  评论(0编辑  收藏  举报