$Description$
有$n$个小朋友坐成一圈,每人有$a_i$个糖果.
每人只能给左右两人传递糖果.
每人每次传递一个糖果代价为$1$.
求使所有人获得均等糖果的最小代价.
$Sol$
感觉超级似曾相识,大概是寒假做过的题目.
求出平均数$x$,然后$a_i-=x$
设$i$小朋友给$i+1$小朋友$b_i$个糖果,特别地,$b_n$表示第$n$个小朋友给第$1$个小朋友的糖果.
$b_n+a_1-b_1=0 Leftrightarrow b_1=a_1+b_n=s_1+b_n$
$b_1+a_2-b_2=0 Leftrightarrow b_2=a_2+b_1=a_1+a_2+b_n=s_2+b_n$
答案为$left |b_1 ight |+left |b_2 ight |+....+left |b_n ight |$
即为$left |s_1+b_n ight |+left |s_2+b_n ight |+....+left |s_n+b_n ight |$
就是$-b_n$到$s_1,s_2,....,s_n$的距离之和,要使之最小,$-b_n$就为$s_1,s_2,....,s_n$的中位数.
$over$
$Code$
#include<bits/stdc++.h> #define il inline #define Rg register #define go(i,a,b) for(Rg int i=a;i<=b;i++) #define yes(i,a,b) for(Rg int i=a;i>=b;i--) #define ll long long #define db double using namespace std; il int read() { int x=0,y=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();} while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();} return x*y; } const int N=1e6+1; int n,a[N]; ll as,s[N]; int main() { n=read(); go(i,1,n)a[i]=read(),s[n]+=a[i]; Rg int ave=s[n]/n,qwq; go(i,1,n)a[i]-=ave,s[i]=s[i-1]+a[i]; sort(s+1,s+n+1); qwq=-s[n/2+1];//qwq=-b[n] go(i,1,n)as+=abs(s[i]+qwq); printf("%lld ",as); return 0; }