您的位置:首页 > 其它

UVA - 11300 Spreading the Wealth(公式推导+中位数)

2017-05-13 10:20 281 查看
点击打开题目链接

Spreading the Wealth

Description

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.

Input

There is a number of inputs. Each input begins with n (n < 1000001), the number of people in the

village. n lines 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.

Output

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

Simple Input

3

100

100

100

4

1

2

5

4

Simple Output

0

4

以前紫书上有一个村庄酒交易的题和本题类似。

题目大意:有n个人围圆桌而坐,每个人有Ai个金币,可以给左右相邻的人一些金币,使得最终所有人金币数相等,求最小金币转移数。

思路:

①所有金币数/人数=m(每个人最终应有的金币数)

②对于任意两个人a,b,a给b n1个金币,b给a n2个金币,则a与b之间关系为(n1-n2)(可正可负);

③对于任意第i个人存在两种关系,给金币给i-1,从i+1获得金币。A[i]-x[i]+x[i+1]=m;

④用x1将其他x表示:

x2=x1-A[i]+m;

x3=x2-A2+m=x1-A[1]-A[2]+2*m;

x4=x3-A3+m=x1-A[1]-A[2]-A[3]+3*m;

···

⑤为了简化,用C[1]=A[1]-m,C[2]=c[1]+A[2]-m ··· ···

则④可表示为:

x2=x1-C[1];

x3=x1-C[2];

x4=x1-C[3];

···

⑥最终结果使得|x1|+|x1-C1|+|x1-C2|+···+|x1-Cn-1|最小。即找到x1,使得到所有C[i]点的距离之和最小。

所以C的中位数为最优解。

附上AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>

using namespace std;
typedef long long ll;
const int maxn = 1e6 + 5;
ll A[maxn];
ll C[maxn];
ll n;
ll sum;
ll m;

int main()
{
ios::sync_with_stdio(false);
while (cin >> n)
{
memset(A, 0, sizeof(A));
memset(C, 0, sizeof(C));
sum = 0;
for (int i = 1; i <= n; i++)
{
cin >> A[i];
sum += A[i];
}
m = sum / n;
for (int i = 1; i < n; i++)
{
C[i] = C[i - 1] + A[i] - m;
}
sort(C, C + n);
ll x1 = C[n / 2], ans = 0;
for (int i = 0; i < n; i++)
{
ans += abs(x1 - C[i]);
}
cout << ans << endl;
}
//  system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva 数学推导