1045: [HAOI2008] 糖果传递

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4897  Solved: 2457
[Submit][Status][Discuss]

Description

有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。

Input

第一行一个正整数nn<=1'000'000,表示小朋友的个数.
接下来n行,每行一个整数ai,表示第i个小朋友得到的糖果的颗数.

Output

求使所有人获得均等糖果的最小代价。

Sample Input

4
1
2
5
4

Sample Output

4
 
毕业被班上委托制作学校录取分布地图。。。没钱拿(눈_눈),我的时间可是10美刀/小时
 
和均分纸牌类似,以绝对值差为贪心原则
设每位小朋友有Ai颗糖,若Xi>0表示第i位小朋友向第i-1位小朋友传递Xi颗糖,若Xi<0表示第i-1位小朋友向第i位小朋友传递Xi颗糖
最终每位小朋友持有ave=(A1+A2...+An)/n颗糖
则:
A1-X1+X2=ave——>X2=X1-(A1-ave)=X1-C1——>C1=A1-ave
A2-X2+X3=ave——>X3=X2-(A2-ave)=X1-C2——>C2=C1+A2-ave
A3-X3+X4=ave——>X4=X3-(A3-ave)=X1-C3——>C3=C2+A3-ave
......
An-Xn+X1=ave——>Xn=Xn-1-(An-ave)=X1-Cn——>Cn=Cn-1+An-ave
于是ans=|X1-C1|+|X2-C2|+|X3-C3|+...+|Xn-Cn|
为了使ans最小,Xi应该最接近Ci的平均数
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 #define LL long long
 8 
 9 const int MAXN=1000005;
10 
11 LL n,mid,ave,ans;
12 LL A[MAXN],C[MAXN];
13 
14 int main()
15 {
16     cin>>n;
17     for(int i=1;i<=n;i++)
18     {
19         cin>>A[i];
20         ave+=A[i];
21     }
22     ave/=n;
23     for(int i=2;i<=n;i++)
24         C[i]=C[i-1]+A[i]-ave;
25     sort(C+1,C+n+1);
26     mid=C[n/2+1];
27     for(int i=1;i<=n;i++)
28         ans+=abs(C[i]-mid);
29     cout<<ans<<endl;
30     return 0;
31 }

 

posted @ 2018-07-15 21:45  InWILL  阅读(471)  评论(0编辑  收藏  举报