UVa 11300 Spreading the Wealth

本题是数学题

1.数学题关键在于建立数学模型。

2.把握中位数。

考虑第i位和第i+1位,有可能是最终i给i+1也可能是i+1给i,假设i给i+1个人则用正数表示,i+1个人给第i个人则用负数表示。则可以建立起数学模型。

设起始每一个人有P个金币,给出去X个金币。设最终每个人用于M个金币。

则有

P1-X1+Xn = M

P2-X2+X1 = M

....

Pn-Xn+X1 = M;

可得

X2 = X1+P2 - M =X1 - C1;

X3 = X2+P2 - M =X1 - C2;

...

Xn = X2+Pn - M = X1-Cn-1;

 

则最终总移动的次数为X1+|X1-C1| +...|X1-Cn-1|

这里用到中位数,C1到Cn-1相当于数轴上的N个点,求X1到N个点的距离最小,则X必在中位数位置上!

 

 

#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stdio.h>

using namespace std;

const int MAX = 1000000+5;

long long p[MAX],c[MAX],sum;
int main(int argc, char *argv[])
{
    
    int n;
    
    while(scanf("%d",&n)!=-1)
    {
        sum = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%lld",p+i);
            sum += p[i];
        }
        long long avg = sum/n;
        
        c[0] = 0;
        for(int i = 1; i < n; i++)
        {
            c[i] = c[i-1] + p[i] - avg;
        }
        
        sort(c+1,c+n);
        long long mid_num = c[n/2];
        
        long long result = mid_num;
        for(int i = 1; i < n; i++)result += abs(mid_num - c[i]);
        printf("%lld\n",result);
        
        
    }    
    
    
    //system("PAUSE");
    return EXIT_SUCCESS;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值