弱智商的碰到这种题就是跪啊!!!!
题意:圆桌坐着N个人,每个人有一定的金币,金币总数能被N整除。每个人能给左右相邻的人一些金币,最终使得每个人的金币数目相等,求被转手金币数量的最小值。
设 xi表示i号给i-1号xi金币,若xi为负,这表示i-1号给i号(-xi)个金币
Ai表示i号一开始持有的金币
则:对与第1个人:A1-X1+X2=M ===>X2=X1-(A1-M);令C1=A1-M
对于第2个人:A2-X2+X3=M ====>x3=x2-(A2-M) ====>x3=x1-(A1+A2-2M);===>x3=x1-C2;
……
对于第n个人:An-Xn+x1=M 这个是个恒等式,无用;
所以我们的答案应该是 |X1|+|X2|+|X3|+……+|Xn|的最小值;
====>|X1|+|X1-C1|+|X1-C2|+……+|Xn-1-Cn|的最小值
故当X1取C数组的中间值时,结果最小。。。
View Code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAXN 1000000+50 #define LL long long LL C[MAXN]; LL A[MAXN]; int n; int main() { while(~scanf("%d",&n)){ LL sum=0; for(int i=0;i<n;i++){ scanf("%lld",&A[i]); sum+=A[i]; } LL M=sum/n; sum=0; for(int i=0;i<n-1;i++){ sum+=A[i]; C[i]=sum-(i+1)*M; } sort(C,C+n-1); LL x=C[(n-1)/2]; LL ans=abs(x); for(int i=0;i<n-1;i++){ ans+=abs(x-C[i]); } cout<<ans<<endl; } return 0; }