您的位置:首页 > 其它

UVA11300——Spreading the Wealth (贪心+建模)

2013-10-21 18:52 363 查看

Problem

A Communist regime is trying to redistribute wealth in a village. They have have decided to sit everyone around a circular table. First, everyone has converted all of their properties to coins of equal value, such
that the total number of coins is divisible by the number of people in the village. Finally, each person gives a number of coins to the person on his right and a number coins to the person on his left, such that in the end, everyone has the same number of
coins. Given the number of coins of each person, compute the minimum number of coins that must be transferred using this method so that everyone has the same number of coins.

The Input

There is a number of inputs. Each input begins with n(n<1000001), the number of people in the village. nlines follow, giving the number of coins of each person
in the village, in counterclockwise order around the table. The total number of coins will fit inside an unsigned 64 bit integer.

The Output

For each input, output the minimum number of coins that must be transferred on a single line.

Sample Input

3
100
100
100
4
1
2
5
4


Sample Output

0
4


分析:

题意是n个人围着圆桌坐,每人都有一些硬币,现在每人都可以

给左右以任意的分配方式给一定的钱,问最小转移多少硬币,使

得每人的硬币数目都一样。

这道题看起来复杂、首先我们设置每个人最初拥有的金币数为

Ai,它给出的金币数为xi,得到的金币数为x(i+1),M表示的是

最后平均每个人需要得到多少个,则可以得到如下:

对于第1个人,A1-x1+x2=M->x2=M-A1+x1=x1-C1(规定C1=A1-

M)对于第2个人,A2-x2+x3=M->x3=M-A2+x2=2M-A1-A2=x1-

C2;对于第3个人,A3-x3+x4=M->x4=M-A3+x3=3M-A1-

A2A3+x1=x1-C3;......

对于第n个人,An-Xn+X1=M,这是一个多余的等式,并不能给我

们更多的信息。

其实从上面我们的处理就可以看出,我们从第一个人和倒数第二

个人的参数信息可以看出其实已经对最后一个人的信息进行了处

理,所以最后一个方程对我们来说并不能给我们带来更多的信

息,则将问题转化为我们希望所有xi的绝对值之和最小,所以问

题就变成了:给定数轴上的n个点,找出一个点到它们的距离之和尽

量小的点。而可以证明的是中位数的点即为我们所需要找的点。

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<ctype.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<math.h>
#include<vector>
#include<map>
#include<deque>
#include<list>
using namespace std;
long long a[1000009],c[1000009];//全部用 long long才能通过~~
long long i,j;
int main()
{
    long long n;
    while(scanf("%lld",&n)!=EOF)
    {
        long long s=0;
        for(i=0; i<n; i++)
        {
            scanf("%lld",&a[i]);
            s+=a[i];
        }
        long long w=s/n;
        for(j=0; j<n; j++)
            c[j]=c[j-1]+a[j]-w;//递推C数组
        sort(c,c+n);
        long long p=c[n/2];
        long long ans=0;
        for(j=0; j<n; j++)
            ans+=abs(p-c[j]);
        printf("%lld\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: