bzoj [HAOI2008] 糖果传递 贪心

来源:互联网 发布:平刷王时时彩软件怎样 编辑:程序博客网 时间:2024/06/04 17:55

                                   bzoj  [HAOI2008] 糖果传递

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1045

Description

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

Input

小朋友个数n 下面n行 ai

Output

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

Sample Input

4
1
2
5
4

Sample Output

4

HINT

数据规模

30% n<=1000

100% n<=100000









 分析:
 假设a1分给an的糖果数为k,则可以得到以下的信息:
                    a1              a2                        a3            an-1              an
 当前数目:a1-k           a2                a3            an-1              an+k
 所需代价:|a1-k-ave| |a1+a2-k-2*ave| |a1+a2+a3-k-3*ave| |a1+..+a(n-1)-k-(n-1)*ave|   |k|
 以sum[i]表示从a1加到ai减掉i*ave的和值,这以上可以化简为
 总代价 = |s1-k|+|s2-k|+...+|s(n-1)-k|+|k|
 不难看出:当k为s1...s(n-1)中的中位数的时候,所需的代价最小



#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define MAXN 2000000using namespace std;long long ave;int n,a[MAXN],c[MAXN];int main(){   scanf("%d",&n);   for(int i=1;i<=n;i++)   {     scanf("%d",&a[i]);     ave+=a[i];   }   ave/=n;   for(int i=1;i<n;i++)   {       c[i]=c[i-1]+a[i]-ave;   }    sort(c,c+n);    long long ans=0;    long long k=c[n/2];    for(int i=0;i<n;i++)    {       ans+=abs(k-c[i]);    }   printf("%lld",ans);   return 0;}



bzoj  [HAOI2008] 糖果传递
bzoj  [HAOI2008] 糖果传递
bzoj  [HAOI2008] 糖果传递
0 0
原创粉丝点击