1. 程式人生 > >【例題】分金幣

【例題】分金幣

題目:圓桌旁坐著n個人,每個人有一定數量的金幣,金幣總數能被n整除。每個人可以給他左右相鄰的人一些金幣,最終使得每個人的金幣數目相等。你的任務是求出被轉手的金幣數量的最小值。比如n=4,且4個人的金幣數量是1,2,5,4時,只需轉移4枚金幣(第三個人給第二個人兩枚金幣,第二和第四個人分別給第一個人一枚金幣)即可實現每人手中的金幣數目相等。

 

利用中位數求解。

總結:|x1-Ci|表示x1到Ci的距離。

中位數離所有頂點的距離之和最小。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1000000+10;
long long A[maxn],C[maxn],tot,M;
int main(){
	int n;
	while(~scanf("%d",&n)){
		tot=0;
		for(int i=1;i<=n;i++){
			scanf("%lld",&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);
		long long x1=C[n/2],ans=0;
		for(int i=0;i<n;i++)
			ans+=abs(x1-C[i]); 	
		printf("%lld\n",ans);
	}
	
	return 0;
}