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;
}
本文介绍了一个经典的算法问题:一群人围成一圈,需将手中的金钱平均分配。通过计算和调整,找到最小化的金钱转移方案,利用中位数的概念解决该问题。
1229

被折叠的 条评论
为什么被折叠?



