cogs 1430. [UVa 11300]分金币
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]分金币的更多相关文章
- UVa 11300 分金币
https://vjudge.net/problem/UVA-11300 题意: 圆桌上有n个人,每个人都有一定的初始金币,每个人可以给他旁边的人一些金币,最终使每个人的金币数相等.计算最少需要转手的 ...
- uva 11300 分金币(利用绝对值加和进行求出最小值)
//qq 767039957 welcome #include<cstdio> #include<algorithm> #include<vector> #incl ...
- 【贪心+中位数】【UVa 11300】 分金币
(解方程建模+中位数求最短累积位移) 分金币(Spreading the Wealth, UVa 11300) 圆桌旁坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一 ...
- UVA - 11300 Spreading the Wealth(数学题)
UVA - 11300 Spreading the Wealth [题目描述] 圆桌旁边坐着n个人,每个人有一定数量的金币,金币的总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金 ...
- uva 11300 - Spreading the Wealth(数论)
题目链接:uva 11300 - Spreading the Wealth 题目大意:有n个人坐在圆桌旁,每个人有一定的金币,金币的总数可以被n整除,现在每个人可以给左右的人一些金币,使得每个人手上的 ...
- UVA.11300 Spreading the Wealth (思维题 中位数模型)
UVA.11300 Spreading the Wealth (思维题) 题意分析 现给出n个人,每个人手中有a[i]个数的金币,每个人能给其左右相邻的人金币,现在要求你安排传递金币的方案,使得每个人 ...
- 数学/思维 UVA 11300 Spreading the Wealth
题目传送门 /* 假设x1为1号给n号的金币数(逆时针),下面类似 a[1] - x1 + x2 = m(平均数) 得x2 = x1 + m - a[1] = x1 - c1; //规定c1 = a[ ...
- 分金币 bzoj 3293
分金币(1s 128M) coin [问题描述] 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的 ...
- UVa 11300 Spreading the Wealth(有钱同使)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New ...
随机推荐
- MYSQL学习笔记三:日期和时间函数
MYSQL学习笔记三:日期和时间函数 1. 获取当前日期的函数和获取当前时间的函数 /*获取当前日期的函数和获取当前时间的函数.将日期以'YYYY-MM-DD'或者'YYYYMMDD'格式返回 */ ...
- IP地址的规划和设计方法(二)
五,IP地址规划方法 (1)IP地址规划的基本步骤 网络地址规划须要按下面6步进行: a)推断用户对网络与主机数的需求: ...
- 32.智能指针auto_ptr
#include <iostream> #include <memory> #include <string> #include <vector> us ...
- tnsnames.ora文件说明
目录位置 unix:$ORACLE_HOME/network/admin WINDOW:%ORACLE_HOME%\network\admin 设置相应的环境变量:TNS_ADMIN tnsname. ...
- pyton写购物车
pyton写购物车 基本要求: 用户输入工资,然后打印购物菜单用户可以不断的购买商品,直到余额不够为止退出时打印用户已购买的商品和剩余金额.. 1.这个程序功能不完整,bug很多,练手之作. good ...
- Android 两步搞定Fragment的返回键
Fragment可以说是在Android开发必需要使用到技术,项目中的界面基本上都是使用Fragment来实现,而Activity只是作为Fragment的载体,但有些特殊情况下Fragment也不得 ...
- PostgreSQL Replication之第二章 理解PostgreSQL的事务日志(4)
2.4 调整检查点和XLOG 目前为止,这一章已经提供深入洞察PostgreSQL如何写入数据,一般来说,XLOG是用来干什么的.考虑到这方面的知识,我们现在可以继续并学习我们能做些什么来使我们的数据 ...
- Xor Sum 2(位运算)
D - Xor Sum 2 Time limit : 2sec / Memory limit : 1024MB Score : 500 points Problem Statement There i ...
- 四舍五入VS银行家舍入法
在学习python的时候,遇见了一个颠覆了我传统观念的四舍五入. 看下面,round()的结果和我们以前根深蒂固的四舍五入是不同的. >>> round(0.5) 0 >> ...
- mysql主从同步错误恢复
Mysql主从同步集群在生成环境使用过程中,如果主从服务器之间网络通信条件差或者数据库数据量非常大,容易导致MYSQL主从同步延迟. MYSQL主从产生延迟之后,一旦主库宕机,会导致部分数据没有及时同 ...