UVA11300 Spreading the Wealth

UVA11300 Spreading the Wealth

请添加图片描述

思路

 对于这道题,我们可以将其转化为一道线性代数的问题,设第 i i i个人的初始值为 A i A_{i} Ai,第 i i i个人给第 i − 1 i-1 i1个人的金币数目为 x i x_{i} xi,设最终值为 a v g avg avg,我们可以得到这样一个等式 A 1 − x 1 + x 2 = a v g A_{1}-x_{1}+x_{2}=avg A1x1+x2=avg,设 C 1 = A 1 − a v g C_{1} = A_{1}-avg C1=A1avg得到 x 1 − x 2 = C 1 → x 2 = x 1 − C 1 ( 1 ) x_{1}-x_{2}=C_{1}\to x_{2}=x_{1}-C_{1}(1) x1x2=C1x2=x1C1(1)

 根据这个式子我们对下面递推的式子进行处理 A 2 − x 2 + x 3 = a v g → x 2 − x 3 = A 2 − a v g → x 3 = x 2 − A 2 + a v g ( 2 ) A_{2}-x_{2}+x_{3}=a vg\to x_{2}-x_{3}=A_{2}-avg\to x_{3}=x_{2}-A_{2}+avg(2) A2x2+x3=avgx2x3=A2avgx3=x2A2+avg(2)

 将 ( 1 ) (1) (1)式带入 ( 2 ) (2) (2)式后,得到 x 3 = x 1 − C 2 ( C 2 = A 1 + A 2 − 2 a v g ) x_{3}=x_{1}-C_{2}(C_{2}=A_{1}+A_{2}-2avg) x3=x1C2(C2=A1+A22avg)

 有这个式子我们可以对下面的n个式子进行递推,可以得到 x n = x 1 − C n − 1 x_{n}=x_{1}-C_{n-1} xn=x1Cn1,而 C n − 1 C_{n-1} Cn1我们是可以解出来的,所以只剩下一个变量 x 1 x_{1} x1,这个式子就变成了一个单变量极值的题目,他的几何意义可以概括为:在一条坐标轴上,有n个坐标分别为 C 1 , C 2 . . . C n C_{1},C_{2}...C_{n} C1,C2...Cn的点,我们要求这个数轴上一点到这个n个数距离之和的最小值,因为这个是一个环,所以最后一点得到的结果为 x 1 x_{1} x1

 要求的结果就是 min ⁡ ∣ x 1 ∣ + ∣ x 1 − C 1 ∣ + . . . . ∣ x 1 − C n − 1 ∣ \min{|x_{1}|+|x_{1}-C_{1}|+....|x_{1}-C_{n-1}|} minx1+x1C1+....x1Cn1,对于这个式子的解,我们可以得到当 x 1 x_{1} x1等于所有点的中位数的时候是最小的。证明这个结论只需要将这个点置于中点,然后向任意一边进行移动可以发现这个数值都是在变大

对于点个数为偶数的情况 x 1 x_{1} x1只需要在中间两个点的区间内即可

code

#include<iostream>
#include<algorithm>
#define N 1010000
#define ll long long
using namespace std;
ll A[N],C[N],sum,m;
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        sum = 1;
        for(int i = 1;i <= n;i++)
        {
            scanf("%lld",&A[i]);
            sum += A[i];
        }
        ll avg = sum/n;
        C[0] = 0;
        for(int i = 1;i < n;i++) C[i] = C[i-1] + A[i] - avg;
        sort(C,C+n);
        ll mid = C[n/2],ans = 0;
        for(int i = 0;i < n;i++) ans += abs(mid - C[i]);
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值