[BZOJ3293] [Cqoi2011] 分金币 (贪心)

Description

  圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除。每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等。你的任务是求出被转手的金币数量的最小值。

Input

  第一行为整数nn>=3),以下n行每行一个正整数,按逆时针顺序给出每个人拥有的金币数。

Output 

  输出被转手金币数量的最小值。

Sample Input

4
1
2
5
4

Sample Output

4

  样例解释
  设四个人编号为1,2,3,4。第3个人给第2个人2个金币(变成1,4,3,4),第2个人和第4个人分别给第1个人1个金币。

HINT

  N<=100000,总金币数<=10^9

Source

Solution

  同$BZOJ1045$,数据范围还小了不少,,,题解在这

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 long long a[100005], s[100005];
 4 int main()
 5 {
 6     int n;
 7     long long ave = 0, ans = 0;
 8     scanf("%d", &n);
 9     for(int i = 1; i <= n; ++i)
10         scanf("%lld", a + i);
11     for(int i = 1; i <= n; ++i)
12         ave += a[i];
13     ave /= n;
14     for(int i = 1; i <= n; ++i)
15         s[i] = s[i - 1] + a[i] - ave;
16     sort(s + 1, s + n + 1);
17     for(int i = 1; i < n / 2 + 1; ++i)
18         ans += s[n / 2 + 1] - s[i];
19     for(int i = n / 2 + 1; i <= n; ++i)
20         ans += s[i] - s[n / 2 + 1];
21     printf("%lld\n", ans);
22     return 0;
23 }
View Code

 

posted @ 2016-06-29 12:28  CtrlCV  阅读(231)  评论(0编辑  收藏  举报