Spreading the Wealth

Problem

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.

The 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.

The Output

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

Sample Input

3
100
100
100
4
1
2
5
4

Sample Output

0
4

 题目大意:圆桌旁边坐着n个人,每人有一定数量的金币,金币总数能被n整除。每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等。你的任务是求出被转手的金币数量的最小值。比如n=4,且4个人的金币数量分别为1,2,5,4时,只需转移4枚金币(第3个人给第2个人2枚金币,第2个人和第4个人分别给第1个人1枚金币)即可实现每人手中的金币数目相等。

 分析:首先最终每个人的金币数量可以计算出来,它等于金币总数除以人数n。接下来用M来表示每个人最终拥有的金币数。

  现在假设编号为 i 的人初始有A枚金币,对于1号来说,他给了4号x1枚金币,还剩A-x1枚金币;但是2号给了他x2枚金币,所以还剩A1-x1+x2枚金币。所以A1-x1+x2=M。同理对于第2个人,有A2-x2+x3=M。最终得到n个方程,实际上只有n-1个有用。

  尝试用x1表示出其他的x,则本题就变成了单变量的极值问题。

  对于第1个人,A1-x1+x2=M x2=M-A1+x1=x1-C1(规定C1=A1-M,下面类似)

  对于第2个人,A2-x2+x3=M x3=M-A2+x2=2M-A1-A2+x1=x1-C2

  对于第3个人,A3-x3+x4=M x4=M-A3+x3=3M-A1-A2-A3+x1=x1-C3

  ...

  对于第n个人,An-xn+x1=M。这是一个多余的等式。

  我们希望所有xi 的绝对值之和尽量小,即|x1|+|x1-C1|+|x1-C2|+...+|x1-Cn-1|要最小。注意到|x1-Ci|的几何意义是数轴上的点x1到C的距离,所以问题变成了:给定数轴上n个点,找出一个到他们距离之和尽量小的点。

  而这个点就是中位数,它实在是太优美,太巧妙了,而且不少其他问题也能用的上,接下来要证明它。

  证明:给定数轴上的n个点,在数轴上的所有点中,中位数离所有顶点的距离之和最小。

  在有6个点的数轴上,任取一点,比如最左边和最右边点的中点K,它的左边有4个点,右边有2个点。把它往左移一点,不要移太多,以免碰到输入点。假设移动的d单位距离,则这个点K左边4个点到它的距离各减少了d,右边的2个点到它的距离各增加了d,但总的来说,距离之和减少了2d。如果K的左边有2个点,右边有4个点,道理类似,不过应该向右移动。

  换句话说,只要灰点左右的输入点不一样多,就不是最优解。所以,如果输入点一共有奇数个,则灰点必须和中间的那个点重合(中位数);如果有偶数个,则灰点可以位于最中间两个点之间的任意位置(还是中位数)。

 代码如下:

 #include<cstdio>
#include<algorithm>
using namespace std; const int maxn = + ;
long long A[maxn], C[maxn], tot, M;
int main() {
int n;
while(scanf("%d", &n) == ) { // 输入数据大,scanf比cin快
tot = ;
for(int i = ; i <= n; i++) { scanf("%lld", &A[i]); tot += A[i]; } // 用%lld输入long long
M = tot / n;
C[] = ;
for(int i = ; i < n; i++) C[i] = C[i-] + A[i] - M; // 递推C数组
sort(C, C+n);
long long x1 = C[n/], ans = ; // 计算x1
for(int i = ; i < n; i++) ans += abs(x1 - C[i]);
// 把x1代入,计算转手的总金币数
printf("%lld\n", ans);
}
return ;
}

另外%lld这个占位符不是跨平台的。虽然cin/cout没有这个问题,但是本题输入量比较大,cin/cout会比较慢。

UVA 11300 Spreading the Wealth (数学推导 中位数)的更多相关文章

  1. UVA.11300 Spreading the Wealth (思维题 中位数模型)

    UVA.11300 Spreading the Wealth (思维题) 题意分析 现给出n个人,每个人手中有a[i]个数的金币,每个人能给其左右相邻的人金币,现在要求你安排传递金币的方案,使得每个人 ...

  2. 数学/思维 UVA 11300 Spreading the Wealth

    题目传送门 /* 假设x1为1号给n号的金币数(逆时针),下面类似 a[1] - x1 + x2 = m(平均数) 得x2 = x1 + m - a[1] = x1 - c1; //规定c1 = a[ ...

  3. UVA - 11300 Spreading the Wealth(数学题)

    UVA - 11300 Spreading the Wealth [题目描述] 圆桌旁边坐着n个人,每个人有一定数量的金币,金币的总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金 ...

  4. UVa 11300 Spreading the Wealth(有钱同使)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New ...

  5. uva 11300 - Spreading the Wealth(数论)

    题目链接:uva 11300 - Spreading the Wealth 题目大意:有n个人坐在圆桌旁,每个人有一定的金币,金币的总数可以被n整除,现在每个人可以给左右的人一些金币,使得每个人手上的 ...

  6. Uva 11300 Spreading the Wealth(递推,中位数)

    Spreading the Wealth Problem A Communist regime is trying to redistribute wealth in a village. They ...

  7. Math - Uva 11300 Spreading the Wealth

    Spreading the Wealth Problem's Link ---------------------------------------------------------------- ...

  8. [ACM_几何] UVA 11300 Spreading the Wealth [分金币 左右给 最终相等 方程组 中位数]

    Problem A Communist regime is trying to redistribute wealth in a village. They have have decided to ...

  9. uva 11300 Spreading the Wealth_数学推倒 + 思维

    这道题和负载平衡问题是同一道题, 如果 n<=100n <= 100n<=100 的话是可以用最小费用流来求解的. 但是题中 nnn 最大可达到 10610^6106, 这就需要我们 ...

随机推荐

  1. ubuntu usb权限问题解决

    在/etc/udev/rules.d/ 创建51-android.rules SUBSYSTEM==" SUBSYSTEM=="

  2. HW2.14

    import java.util.Scanner; public class Solution { public static void main(String[] args) { final dou ...

  3. CF29D - Ant on the Tree(DFS)

    题目大意 给定一棵树,要求你按给定的叶子节点顺序对整棵树进行遍历,并且恰好经过2*n-1个点,输出任意一条符合要求的路径 题解 每次从叶子节点开始遍历到上一个叶子节点就OK了, 这个就是符合要求的路径 ...

  4. 【转】科普Spark,Spark是什么,如何使用Spark

    本博文是转自如下链接,为了方便自己查阅学习和他人交流.感谢原博主的提供! http://www.aboutyun.com/thread-6849-1-1.html http://www.aboutyu ...

  5. 问题-[Delphi7]程序在WIN7电脑上的日期错误处理

    问题现象:我想大家都遇到过在XP上没有问题的日期格式,到了WIN7之后就不行了. 问题原因:因为在WIN7中增加了新的日期格式,但是老的DELPHI未处理(如果我说错了,希望高人指点). 问题处理: ...

  6. python 一些重要的内建异常类

  7. lettCode-Array

    1   Remove Element    lintcode-172 描述: 删相同元素,反现有长度 记忆:标不同元素,反标记值 public int removeElement(int[] a, i ...

  8. Android+OpenCV 摄像头实时识别模板图像并跟踪

    通过电脑摄像头识别事先指定的模板图像,实时跟踪模板图像的移动[用灰色矩形框标识] ps:一开始以为必须使用OpenCV Manager,可是这样会导致还需要用户去额外安装一个apk,造成用户体验很差, ...

  9. JAVA编程心得-多态设计初步

    面向对象的思想中,封装,继承,多态作为特性会在开发中广泛应用,一个健壮的系统除了功能强大以外,它的可扩展性应该也很强,多态恰好应用了这个思路. 下面我以杨小聪去某地的方式为例,我们知道首先杨小聪要去某 ...

  10. [欧拉] poj 2230 Watchcow

    主题链接: http://poj.org/problem? id=2230 Watchcow Time Limit: 3000MS   Memory Limit: 65536K Total Submi ...