• 【BZOJ 1045】 1045: [HAOI2008] 糖果传递


    1045: [HAOI2008] 糖果传递

    Description

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

    Input

      第一行一个正整数n<=987654321,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的
    糖果的颗数.

    Output

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

    Sample Input

    4
    1
    2
    5
    4

    Sample Output

    4
     
     
    【分析】
      一道经典题。
      设xi为i给i-1多少个糖果(负的表示反向给),x1表示1给n多少个糖果。
      设M为平均数。
      有:
      a1-x1+X2=M -> x2=M-a1+x1
      a2-x2+x3=M -> x3=M-a2+x2=2M-a1-a2+x1
      .....
      an-xn+x1=M
      观察一下,设ci=ai-M
      则:
      x2=x1-c1
      x3=x1-c2
      ...
      就是求|x1|+|x1-c1|+|x1-c2|+...+|x1-cn-1|的最小值,变成了经典的数学的绝对值不等式的题目。
      在数轴上表示成点到点的距离,就知道x1取所有C的中位数既有最小值。
     
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 #define Maxn 10000010
     9 #define LL long long
    10 
    11 LL a[Maxn],c[Maxn],M;
    12 
    13 LL myabs(LL x) {return x>0?x:-x;}
    14 
    15 int main()
    16 {
    17     int n;
    18     scanf("%d",&n);
    19     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    20     M=0;
    21     for(int i=1;i<=n;i++) M+=a[i];
    22     M/=n;
    23     c[0]=0;
    24     for(int i=1;i<n;i++) c[i]=c[i-1]+a[i]-M;
    25     sort(c,c+n);
    26     LL now=c[n/2],ans=0;
    27     for(int i=0;i<n;i++) ans+=myabs(c[i]-now);
    28     printf("%lld
    ",ans);
    29     return 0;
    30 }
    View Code

    %%%大颓果

    2016-12-13 16:53:51

  • 相关阅读:
    时尚生活小秘方[转载]
    武侠片上的99个公式镜头
    SQL语句优化技术分析
    LoadRunner监视的性能计数器
    圣诞收到最搞笑的短信两则
    loadrunner 运行状态描述
    ORACLE 常用脚本[转载]
    关于内存泄漏检测问题,和大家一起分享
    小笑话
    [转贴] ++ 一个北大女孩给男友的道歉信(爆笑!!!)相当经典
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6170582.html
Copyright © 2020-2023  润新知