1045: [HAOI2008] 糖果传递
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
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 }