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

    题目

    有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。求使所有人获得均等糖果的最小代价。

    分析

    又是以前弄懂了,第二次做又不会了,下面自己手打一遍数学证明吧

    设 give[i]为第i个人给第i-1个人的糖果数量,a[i]为本身的糖果数量

    设均等的糖果数为 ave=sum/n

    则 a[1]+give[2]-give[1]=ave

    a[2]+give[3]-give[2]=ave

    ·········

    移项

    give[2]=give[1]+ave-a[1]

    give[3]=give[2]+ave-a[2]=give[1]+ave-a[1]+ave-a[2]

    可以观察到有一个 ave-a[i]的部分

    设b[i]=a[i]-ave 再设c[i]为b数组的前缀和

    则有 give[i]=give[1]-c[i-1]

    give[1]+give[2]+·······+give[n]=| c[0]-give[1] |+| c[1]-give[1] |+······+| c[n-1]-give[1] |

    相当于求数轴上的n个点到一定点的距离和的最小值

    就是初一数学学的, 所以give[1]取序列c的中位数即可

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1001000
    #define ll long long
    ll n,sum,aver,minx,ans;
    ll a[N],c[N];
    inline void read(ll &x)
    {
        x=0;char ch=getchar();
        while(ch>'9'||ch<'0'){ch=getchar();}
        while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
    }
    int main()
    {
        read(n);
        for(int i=1;i<=n;i++)
            read(a[i]),sum+=a[i];
        aver=sum/n;
        for(int i=1;i<=n;i++)
            c[i]=c[i-1]-aver+a[i];
        sort(c+1,c+1+n);
        minx=c[(n+1)>>1];
        for(int i=1;i<=n;i++)
            ans+=abs(c[i]-minx);
        printf("%lld
    ",ans);
        return 0;
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    函数式编程
    javascript RegExp类型 学习小记
    javascript Date类型 学习笔记
    post 提交数据
    git学习笔记
    Winform DevExpress控件库(一) 使用SplashScreenManager控件定制程序加载页面
    .net 对json数据进行读取
    [WPF]TextTrimming截断后,ToolTip显示完整信息
    删除程序自身
    c/s项目记住账号密码功能
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9637694.html
Copyright © 2011-2022 走看看