• 糖果传递 (环状的均分纸牌)


     糖果传递 (环状的均分纸牌)

    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

    /*
    环状均分纸牌
    
    显然最后每个人都剩下sum/n张纸牌,p[i]表示这个人给下一个人多少张纸牌
    
    显然p[i]=a[i]+p[i-1]-sum/n
    
    p[i]-p[i-1]=a[i]-sum/n,所以p[i]-p[i-1]+p[i-1]-p[i-2]+.....-p[1] = sigma(i)(a[i]-sum/n)
    
    即p[i]=sigma(i)(a[i]-sum/n)+p[1]
    
    显然sigma(i)(a[i]-sum/n)是定值,所以p[1]是所有sigma(i)(a[i]-sum/n)的中位数就好了
    
    ….................................................................................................................................
    
    我们用xi表示第i个小朋友给第i−1个小朋友的糖果数,其中x1表示第1个小朋友给第n个朋友的糖果数,那么最终答案即为|x1|+|x2|+...|xn|。
    我们假设最后每个人剩avg个糖果,那么可以得到:
    对于第一个小朋友:a1+x2−x1=avg
    对于第二个小朋友:a2+x3−x2=avg
    …
    对于最后一个小朋友:an+x1−xn=avg
    整理一下即可得到:
    x2=avg−a1+x1
    x3=avg−a2+x2=2avg+x1−a2−a1
    …
    xn=avg−an−1+xn−1=(n−1)avg+x1−∑n−1i=1ai
    我们令ci=∑ij=1ai+i×avg,上述式子即可转化为求解|x1|+|x1−c1|+|x1−c2|...+|x1−cn−1|的最小值,那么直接令x1等于c的中位数即可。
    */
    
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    using namespace std;
     int a[1000005],c[1000005];
    int main()
    {
        int n;
        cin>>n;
        long long sum=0,x=0,m;
        for(int i=1;i<=n;i++)
        {
           scanf("%d",&a[i]);
            sum+=a[i];
        }
        m=sum/n;
        for(int i=2;i<=n;i++)   c[i]=c[i-1]+a[i]-m;
        sort(c+1,c+n+1);
        for(int i=1;i<=n;i++)  x+=abs(c[i]-c[(n+1)/2]);
         printf("%lld
    ",x);
        return 0;
    }
  • 相关阅读:
    1
    Dockerfile概述
    协议
    部署环境
    协议与数据2
    【笔记】刚到公司,初识dll
    C#Winform学习笔记
    VS2019添加VisionPro控件(此方法是大师分享的)
    VisionPro脚本
    Visionpro相机取像操作,.NET4.0
  • 原文地址:https://www.cnblogs.com/fenhong/p/6574087.html
Copyright © 2020-2023  润新知