zoukankan      html  css  js  c++  java
  • HYSBZ-1045 糖果传递

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

    假设当所有人获得均等的糖果的时候:

    1. 每个人手上的糖果的数量为(ave)

    2. (i)个人初始时的糖果数量为(A_i)

    3. (i)个人给了前一个人(X_i)个糖果(如果(X_i)是负数,代表前一个人实际上的给了第(i)个人(X_i)个糖果)

    那么对于每个人,都满足等式

    [A_i-X_i+X_{(i+1)\%n}=ave ]

    然后可以列出n条等式

    [A_0-X_0+X_1=ave\ A_1-X_1+X_2=ave\ ...\ A_{n-1}-X_{n-1}+X_0=ave\ ]

    最终的答案应该是(sum_{i=0}^{n-1}|X_{i}|)

    实际上以上的其中一条等式能够由其他的(n-1)条等式得到.

    不同的等式只有(n-1)条,未知数有(n)个,不能直接解.

    假设(X_0)是已知的值,可以推出所有的(X)的值

    [X_1=ave-A_0+X_0=X_0-(A_0-ave)\ X_2=ave-A_1+X_1=X_1-(A_1-ave)=X_0-(A_0-ave)-(A_1-ave)\ ...\ X_{n-1}=X_0-sum_{i=0}^{n-2}(A_i-ave) ]

    定义(C_k=C_{k-1}-(A_i-ave))

    那么(|X_k|=|X_0-C_k|)

    如何让(sum_{i=0}^{n-1}|X_{i}|)变得尽量小,

    可以发现,(|X_0-C_k|)可以看作是数轴上(X_0)(C_k)的距离,

    (X_0),(C_1),(C_2),...,(C_{n-1}),都列在一条数轴上,

    找到其中的一个点,让这个点到其他所有的点的距离的和最小.

    显然,这几个点之中最靠中间的点,就是到其他所有点的距离的和最小的点.

    那么这个距离的和就是答案

    应该如何假设(X_0)的值?

    (X_0)的含义是第(0)个人给第(n-1)个人的糖果的数量.

    实际上,从第二个人开始,每人给前一个人(X_i)个糖果,到最后第(n-1)个人手上的糖果数就应该是(ave)了.

    所以(X_0)应该是(0).

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    
    static ll n, sum, ave, mid, ans, a[1100100], c[1100100];
    
    int main()
    {
        scanf("%lld", &n);
        for(ll i = 0; i < n; ++i)
        {
            scanf("%lld", &a[i]);
            sum += a[i];
        }
        ave = sum/n;
    
        c[0] = 0;
        for(int i = 1; i < n; ++i)
        {
            c[i] = c[i-1]+a[i]-ave;
        }
    
        sort(c, c+n);
        mid = c[n/2];
        for(int i = 0; i < n; ++i)
            ans += abs(c[i] - mid);
        printf("%lld
    ", ans);
    }
    
    
  • 相关阅读:
    洛谷 P1725 琪露诺 题解
    洛谷 P1714 切蛋糕 题解
    洛谷 P1352 没有上司的舞会 题解
    洛谷 P1194 买礼物 题解
    洛谷 P2872 [USACO07DEC]道路建设Building Roads 题解
    OpenCV之头文件分析
    电路学习之二极管(一)
    二极管学习(一)
    STL之vetor 排序
    小波分析(二)
  • 原文地址:https://www.cnblogs.com/zzidun-pavo/p/12482756.html
Copyright © 2011-2022 走看看