码迷,mamicode.com
首页 > 其他好文 > 详细

UVa11300 - Spreading the Wealth

时间:2016-09-09 23:46:57      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:

题意

n个人围成一圈,每个人都有一定数量的金币,金币总数可被n整除,现可将手中金币给左右相邻的人,最终使每人手中的金币数相等,求最少转移的金币数量。

思路

设a[i]给了a[i-1]x1个金币,从a[i+1]拿到x2个金币,则有

a1-x1+x2 = m (此时x1为给an的金币数) 另 c1 = a1 - m   则 x2 = x1 -c1

a2-x2+x3 = m ,则c2 = c1+a1-m   x3 = x1 - c2

...

|x1| + |x1-C1|+...+|x1-Cn-1|,要求这个最小,那么就是要x1为这些数的中位数

总结

学会数学分析的方法,总结规律并转换成代码

 

#include <iostream>
#include <cstdio>
#include <algorithm>
typedef long long LL;
const int maxn = 1e6 + 5;
LL a[maxn],c[maxn],tot,m; //数组a为每个人金币的数量 m为最后相等时的金币数
using namespace std;

int main()
{
    int n;
    while(scanf("%d",&n) == 1) {
        tot = 0;
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
            tot += a[i];
        }
        m = tot / n;
        c[0] = 0;
        for(int i = 1; i < n; i++) {
            c[i] = c[i-1] + a[i] - m;
        }
        sort(c,c+n);
        LL x1 = c[n/2],ans = 0;
        for(int i = 0; i < n; i++) {
            ans += abs(x1 - c[i]);
        }
        cout << ans <<endl;
    }
    return 0;
}

 

UVa11300 - Spreading the Wealth

标签:

原文地址:http://www.cnblogs.com/md-zz/p/5858230.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!