1430. [UVa 11300]分金币

★☆   输入文件:Wealth.in   输出文件:Wealth.out   简单对比
时间限制:1 s   内存限制:256 MB

【题目描述】

圆桌旁坐着n个人,每个人有一定数量的金币,金币数总能被n整除。每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数相等。你的任务是求出被转手的金币数量最小值。

比如,n=4,且4个人的金币数分别是1,2,5,4时,只需转移4枚金币(第3个人给第2个人2枚金币,第2个人和第4个人分别给第一个人1枚金币)即可实现每人手中的金币数相等。

【输入格式】

输入包括多组数据。每组数据的第一行为整数n(n≤1 000 000),以下n行每行为一个整数,按逆时针的顺序给出每个人拥有的金币数。输入结束标志为文件结束符(EOF).

【输出格式】

对于每组数据,输出被转手的金币数量的最小值。

输入保证这个值在64位无符号整数范围内。

【样例输入】

3
100
100
100
4
1
2
5
4

【样例输出】

0
4
【题目来源】
Spreading the Wealth ,UVa 11300

思路:  

  这道题目看起来很复杂,让我们慢慢分析。首先,最终每个人的金币数量可以计算出来,他等于金币总数除以人数n。接下来我们用M来表示每个人最终拥有的金币数。

  假设有4个人,按顺序编号为1,2,3,。假设1号给2号3枚金币,然后2号又给了1号5枚金币,这实际上等价于2号给1号2枚金币,而1号什么也没给2号。这样,可以设x2表示2号给了1号多少金币。如果x2<0,说明实际上是1给了2号-x2,枚金币。x1,x3和x4的含义类似。注意:由于是环形,x1指的是1号给4号多少金币。  现在假设编号为i的人初始有Ai枚金币。对于1号来说,他给了4号x1枚金币,还剩A1-x1枚;但因为2号给了他x2枚金币,所以最后还剩A1-x1+x2枚金币。根据题设,该金币数等于M。换句话说,我们得到了一个方程:A1-x1+x2=M。

  同理,对于第2个人,有A2-X2+X3=M。最终,我们可以得到n个方程,一共有n个变量,是不是可以直接解方程组了呢?很可惜,还是不行。因为从前n-1个人方程可以推导出最后一个方程。所以,实际上只有n-1个方程是有用的。

  尽管无法直接解出答案,我们还是可以尝试着用x1表示出其他的xi,则本题就变成了单变量的极值问题。

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

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

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

    ······    

    对于第n个人,An-xn+x1=M。(这是一个多余的等式,并不能给我们更多的信息)  

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

    可以猜想到这个最优的x1就是这些数的“中位数”(即排序以后位于中间的数),因此只要排个序就可以了。     证明:注意,我们要证明的是:给定数轴上的n个点,在数轴上的所有点中,中位数离所有顶点的距离之和最小。凡是能转化为这个模型的题目都可以用中位数求解并不只适用于本题。     画出来后如下图所示:

     任意找一个点,比如上图中的灰点。他的左边有4个输入点,右边有2个输入点。把他往左移动一点,不要移的太多,以免碰到输入点。假设移动了d单位距离。则灰点左边4个点到他的距离个减少了d,右边两个点到他的距离各增加了d,但总的来说,距离之和减少了2d。

     如果灰点左边有2个点,右边有4个点,道理类似,不过应该向右移动。换句话说,只要灰点左右的输入点数不一样多,就不是最优解。什么情况下左右的输入点一样多呢?如果输入点一共有奇数个,则灰点必须和中间的那个点重合(中位数);如果有偶数个,则灰点可以位于最中间的两个点之间的任意位置(还是中位数)。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1000100
using namespace std;
long long n,tot,ans;
long long val[MAXN],C[MAXN];
int main(){
freopen("Wealth.in","r",stdin);
freopen("Wealth.out","w",stdout);
while(scanf("%d",&n)!=EOF){
tot=;
for(int i=;i<=n;i++){
scanf("%I64d",&val[i]);
tot+=val[i];
}
tot/=n;C[]=;
for(int i=;i<n;i++)
C[i]=C[i-]+val[i]-tot;
sort(C,C+n);
long long x1=C[n/];ans=;
for(int i=;i<n;i++) ans+=abs(x1-C[i]);
printf("%I64d\n",ans);
}
}

cogs 1430. [UVa 11300]分金币的更多相关文章

  1. UVa 11300 分金币

    https://vjudge.net/problem/UVA-11300 题意: 圆桌上有n个人,每个人都有一定的初始金币,每个人可以给他旁边的人一些金币,最终使每个人的金币数相等.计算最少需要转手的 ...

  2. uva 11300 分金币(利用绝对值加和进行求出最小值)

    //qq 767039957 welcome #include<cstdio> #include<algorithm> #include<vector> #incl ...

  3. 【贪心+中位数】【UVa 11300】 分金币

    (解方程建模+中位数求最短累积位移) 分金币(Spreading the Wealth, UVa 11300) 圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一 ...

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

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

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

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

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

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

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

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

  8. 分金币 bzoj 3293

    分金币(1s 128M)  coin [问题描述] 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的 ...

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

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

随机推荐

  1. 用html语言写一个功课表

    今天在网上看了一个关于html的教程,主要是讲表格,看完之后认为有必要上机试试.于是就写了以下的一段代码. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvb ...

  2. Struts2 | struts.xml文件中使用method属性和通配符简化action标签和Action处理类的编写

    转自:https://www.jianshu.com/p/310e89ee762d 在Struts2框架中,我们知道基本的Action标签只能实现一个url请求对应一个Action处理类.那么我们如果 ...

  3. MVC自定义错误日志异常处理

    MVC添加错误日志处理模块很简单,只要写个继承自HandleErrorAttribute的过滤器,重新OnException方法,贴个异常处理代码如下: public class ExceptionA ...

  4. 以下三种下载方式有什么不同?如何用python模拟下载器下载?

    问题始于一个链接https://i1.pixiv.net/img-zip-...这个链接在浏览器打开,会直接下载一个不完整的zip文件 但是,使用下载器下载却是完整文件 而当我尝试使用python下载 ...

  5. jqueryEasyUI form表单提交的一个困惑

    今天用到了jqueryEasyUI的form表单做一个增加操作的提交,想打开调试(用的是火狐)看看传的参数,但是怎么也看不到form表单提交的http请求?而且还会发送一个另外的请求! 在页面加载时, ...

  6. hiho1515 - 数据结构 并查集

    题目链接 小Hi的学校总共有N名学生,编号1-N.学校刚刚进行了一场全校的古诗文水平测验. 学校没有公布测验的成绩,所以小Hi只能得到一些小道消息,例如X号同学的分数比Y号同学的分数高S分. 小Hi想 ...

  7. CMake入门之创建一个基于PCL的最小工程

    最近在学习PCL,借助Cmake可省去繁琐的添加包含目录和依赖库操作. 一个典型的CMakeLists.txt内容通常为: cmake_minimum_required(VERSION 2.6 FAT ...

  8. Java基础学习总结(11)——重载与重写

    首先我们来讲讲:重载(Overloading) 一.方法的重载 方法名一样,但参数不一样,这就是重载(overload). 所谓的参数不一样,主要有两点:第一是参数的个数不一样,第二是参数的类型不一样 ...

  9. Android编译环境配置

    Android编译环境配置 网上关于Android编译环境配置的整理资料有不少,经整理亲测后,希望能给需要的亲们提供帮助. 主要分为四步: 1.安装JDK(Java Standard Edition ...

  10. 洛谷 P2440 木材加工

    P2440 木材加工 题目背景 要保护环境 题目描述 题目描述: 木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头(木头有可能有 剩余),需要得到的小段的数目是给定的.当然,我们希望得到 ...