[bzoj1045][HAOI2008] 糖果传递【构造】

【题目链接】
  http://www.lydsy.com/JudgeOnline/problem.php?id=1045
【题解】
  记X[i]为从第i堆向第i+1堆转移的数量。(第n堆转移到1
  那么有a[i]X[i]+X[i1]=average
  X[i]=a[i]+X[i1]average
  移项得:X[1]=a[1]+X[n]avarage
      X[2]=a[2]+X[1]avarage
      =a[2]+a[1]+X[n]2average
    X[i]=j=1ia[i]X[n]iavarage
  记S[i]=j=1ia[i]iavarage
 有X[i]=S[i]X[n]
 ans=i=1n|X[n]S[i]|
 当X[n]S[i]中位数的时候ans取到最小值。
 复杂度O(nlog2n)

/* --------------
    user Vanisher
    problem bzoj-1045 
----------------*/
# include <bits/stdc++.h>
# define    ll      long long
# define    inf     0x3f3f3f3f
# define    N       1000100
using namespace std;
ll read(){
    ll tmp=0, fh=1; char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
    while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
    return tmp*fh;
}
ll a[N],cnt,n,s[N],ans,now;
int main(){
    n=read();
    for (ll i=1; i<=n; i++)
        a[i]=read(), cnt+=a[i];
    cnt=cnt/n;
    for (ll i=1; i<=n; i++)
        s[i]=a[i]-cnt+s[i-1];
    sort(s+1,s+n+1);
    now=s[(1+n)/2];
    for (ll i=1; i<=n; i++)
        ans=ans+abs(s[i]-now);
    printf("%lld\n",ans);
    return 0;
}

同[bzoj1465][bzoj3293]

posted @ 2018-03-07 18:03  Vanisher  阅读(80)  评论(0编辑  收藏  举报