阿里

转载自:http://www.cnblogs.com/yejinru/archive/2012/12/29/2838467.html,尊重原创!

/*
* 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1045
* 有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传
* 递一个糖果代价为1,求使所有人获得均等糖果的最小代价。
*
* 分析:
* 假设a1分给an的糖果数为k,则可以得到以下的信息:
*                a1              a2                        a3            an-1              an
* 当前数目:a1-k           a2          a3            an-1              an+k
* 所需代价:|a1-k-ave| |a1+a2-k-2*ave| |a1+a2+a3-k-3*ave| |a1+..+a(n-1)-k-(n-1)*ave|   |k|
* 以sum[i]表示从a1加到ai减掉i*ave的和值,这以上可以化简为
* 总代价 = |s1-k|+|s2-k|+...+|s(n-1)-k|+|k|
* 不难看出:当k为s1...s(n-1)中的中位数的时候,所需的代价最小
*
* */

 

 1 <span style="font-size: 15px;">#include <cstdio>
 2 
 3 #include <cstring>
 4 
 5 #include <iostream>
 6 
 7 #include <algorithm>
 8 
 9  
10 
11 using namespace std;
12 
13  
14 
15 const int X = 1000005;
16 
17  
18 
19 typedef long long ll;
20 
21  
22 
23 ll sum[X],a[X];
24 
25 ll n;
26 
27  
28 
29 ll Abs(ll x){
30 
31     return max(x,-x);
32 
33 }
34 
35  
36 
37 int main(){
38 
39     //freopen("sum.in","r",stdin);
40 
41     while(cin>>n){
42 
43         ll x;
44 
45         ll tot = 0;
46 
47         for(int i=1;i<=n;i++){
48 
49             scanf("%lld",&a[i]);
50 
51             tot += a[i];
52 
53         }
54 
55          
56 
57         ll ave = tot/n;
58 
59         for(int i=1;i<n;i++)
60 
61             sum[i] = a[i]+sum[i-1]-ave;
62 
63         sort(sum+1,sum+n);
64 
65          
66 
67         ll mid = sum[n/2];
68 
69         ll ans = Abs(mid);
70 
71          
72 
73         for(int i=1;i<n;i++)
74 
75             ans += Abs(sum[i]-mid);
76 
77         cout<<ans<<endl;
78 
79     }
80 
81     return 0;
82 
83 }
84 
85 </span>

 

 

 

posted @ 2013-05-05 16:30  little_star  阅读(208)  评论(0编辑  收藏  举报