uva11300 分金币(中位数)

来源:https://vjudge.net/problem/UVA-11300

题意:

   有n个人围成一圈,每个人有一定数量的金币,每次只能挪动一个位置,求挪动的最少金币使他们平分金币

题解:

蓝书p6

令x1为1号给2号的金币数,负数代表反方向   x2为2号给3号的金币数      x3为3号给4号的金币数

 

而a1-x1+xn=m(m为平均数)a2-x2+x1=m    a3-x3+x2=m

我们要求的就是|x1|+|x2|+|x3|+...|xn|

用x1表示x2,x3,x4

ans=|x1|+|x1-G1|+|x1-G2|....

x1到n个点的距离和最短时,就是正解

而这个点==G[MID]

#include <cstdio>
#include <algorithm>
#include <iostream>
#define ll long long
using namespace std;
const int maxn=1000000+5;

ll num[maxn];
int main()
{
	int n;
  	while(scanf("%d",&n)!=EOF)
	{
	    ll  sum=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%lld",&num[i]);
			sum+=num[i];
		}
        ll M=sum/n;
		num[1]=0;
		for(int i=2;i<=n;i++)
			num[i]=M-num[i]+num[i-1];
 		sort(num+1,num+1+n);
        int mid=n/2+1;
	    ll ans=0;
		for(int i=1;i<=n;i++)
			ans+=abs(num[mid]-num[i]);
		printf("%lld\n",ans);
	}
	return 0;
}

  

posted @ 2018-05-24 18:17  czh~  阅读(297)  评论(0编辑  收藏  举报