zoukankan      html  css  js  c++  java
  • 【bzoj1045】【HAOI2008】 糖果传递

    Description

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

    Input

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

    Output

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

    Sample Input

    4
    1
    2
    5
    4

    Sample Output

    4

    题解:

      膜黄学长。

      首先求出平均数$p$,然后设$x_{i}$表示第i个人要给第$i-1(MOD)n$个人糖果的数量,然后得到$n$个形如$p==a_{i}-x_{i}+x_{i+1}$的方程。

      全部展开就是:

      $$p==a_{1}-x_{1}+x_{2} ightarrow x_{2}==p-a_{1}+x_{1}$$

      $$p==a_{2}-x_{2}+x_{3} ightarrow x_{3}==2p-a_{1}-a_{2}+x_{1}$$

      $$...$$

      $$p==a_{n}-x_{n}+x{1} ightarrow x_{1}==x_{1}$$

      此时我们设$f_{i}=sum_{x=1}^{i-1}a_{i}-(i-1)p$,上面的方程就可以写作:

      $$x_{2}==x_{1}-f_{2}$$

      $$x_{3}==x_{1}-f_{3}$$

      $$...$$

      $$x_{1}==x_{1}$$

      所以$ans=sum_{i=1}^{n}|x_{i}|=sum_{i=1}^{n}|x_{1}-f_{i}|$。

      将其转化到数轴上就是求一个点$x_{1}$,使此点距离所有的$f_{i}$之和最小。

      然后思考,将$f$排序,假设$f_{i}<=x_{1}<=f_{i+1},iin[1,n]$(显然我们可以知道,$x_{1}$小于或大于$f$极值是不优的)。

      那么我们可以将$f$数组从i这个位置分成两部分。

      我们先假设$i<frac{n}{2}$($i>frac{n}{2}$可以类比)。

      $$ans=sum_{j=1}^{i}(f_{n-j+1}-f_{x})+sum_{j=i+1}^{n-i}f_{j}-x_{1}$$

      再化简一下就是:

      $$ans=sum_{j=1}^{frac{n}{2}}(f_{n-j+1}-f_{j})+sum_{j=i+1}^{frac{n}{2}}2(f_{i}-x_{1})$$

      然后就显然了,当我们让后面的最小时,答案最小。

      所以时,答案最小。

      记得开long long。

    #include<cstdio>
    #include<algorithm>
    const int N=(int)1e6+10;
    inline int read(){
    int s=0,k=1;char ch=getchar();
      while(ch<'0'||ch>'9') k=ch=='-'?-1:k,ch=getchar();
      while(ch>47&&ch<='9') s=s*10+(ch^48),ch=getchar();
      return s*k;
    }
    int n;
    int a[N],f[N];
    inline int abs(int x){return x>0?x:-x;}
    int main(){
      n=read();
      long long tot=0;
      for(int i=1;i<=n;i++){
        tot+=(a[i]=read());
      }
      tot/=n;
      f[1]=0;
      for(int i=2;i<=n;i++)
      f[i]=f[i-1]-tot+a[i];
      std::sort(f+1,f+n+1);
      int mid=f[(n>>1)+1];
      long long ans=0;
      for(int i=1;i<=n;i++)
      ans+=abs(f[i]-mid);
      printf("%lld ",ans);
    }
  • 相关阅读:
    oracle 中和mysql的group_concat有同样作用的写法
    sql find_in_set在oracle下的解决方案
    Django项目部署:使用uwsgi和nginx的方式
    virtualenvwrapper.sh报错: There was a problem running the initialization hooks.解决
    html中footer如何一直保持在页底
    mysqldump导出备份数据库报Table ‘performance_schema.session_variables‘ doesn‘t exist
    django-ckeditor添加代码功能(codesnippet)
    Django_外键查询和反查询
    python面向对象编程(OOP)
    Django模型中字段属性choice的使用
  • 原文地址:https://www.cnblogs.com/Troywar/p/7458787.html
Copyright © 2011-2022 走看看