UVA 11300 - Spreading the Wealth(代数分析+距离和最小)

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33899

题意: 

题意:n个人坐成一圈,每个人有一些钱,现在要平分这些钱,每个人只能把钱给周围的人,问最少要转移多少钱才能平分

  

思路: 可以得到最终得钱数 为M,Xi为他给上一个人的钱,那么每个人最后的钱就是: A[I]-Xi+X(i+1)=M

列出n-1个公式,最后全部xi用  Xi=X1-C表示,那么答案就是 |X1|+|X2|+......+|Xn|=| X1 |+|X1-C1|+......+|Xn-C(n-1) | 

并且可以推得C之间的关系是   Cn=C(n-1) +An -M     ,通过C[0]=0,可以求得全部的Ci

 | X1 |+|X1-C1|+......+|X1-C(n-1) |  

就是  数轴上 n个点到X1的距离之和 

如何选择一个点到使得上述距离最小...

这个点就是n个数的中位数,也就是最中间的点



.

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
long long tm[1000006]; 
int main()
{
	
	
	int n,i; 
	while(scanf("%d",&n)!=EOF)
	{
		long long sum=0;	
		for (i=1;i<=n;i++)
		{
			scanf("%lld",&tm[i]);
			sum+=tm[i];
		}
		long long avg=sum/n;
		tm[0]=0;
		for(i=1;i<n;i++)
		{ 
			tm[i]=tm[i-1]+tm[i]-avg;
		}
		sort(tm,tm+n);
		long long x=tm[n/2];
		long long ans=0;
		for (i=0;i<n;i++)
		{
			ans+=abs(tm[i]-x);
		}
		cout<<ans<<endl;  
		
		
	}	
	
	
	
	return 0;
	
} 

你可能感兴趣的:(UVA 11300 - Spreading the Wealth(代数分析+距离和最小))