UVA.11300 Spreading the Wealth (思维题 中位数模型)
UVA.11300 Spreading the Wealth (思维题)
题意分析
现给出n个人,每个人手中有a[i]个数的金币,每个人能给其左右相邻的人金币,现在要求你安排传递金币的方案,使得每个人手中的金币个数相等,并求出转移金币的最小个数。保证(Σa[i])/n为整数。
第一眼没有思绪,这种推导方式还是第一次见到。
设ai为第i个人初始金币数量,xi为第i个人转移给i-1个人金币的数量(i为1表示转移给第n个人),(Σa[i])/n = m。
有了上述的基础,可以写出每个人的金币表达式:
即每个人最终的金币数量 = 他的初始化数量-转移走的数量+转移来的数量
a1 - x1 + x2 = m
a2 - x2 + x3 = m
a3 - x3 + x4 = m
……
an - xn + x1 = m
可以写出n个式子,但是这n个式子中只有n-1个有用,因为任意一个式子都可以由剩下的n-1个式子推出。读者可以一试:将1至n-1个式子叠加,可以得到第n个式子。
于是我们要想办法利用这n-1个式子,关键就是:转换成单变量。
我们此处都转换成以x1为变量的式子,即用x1表示xi(i≠1):
x2 = m-a1+x1
x3 = m-a2+x2 = m-a2+m-a1+x1 = 2m-a2-a1+x1
x4 = m-a3+x3 = m-a3+2m-a2-a1+x1 = 3m-a3-a2-a1+x1
……
xn = (n-1)m - Σai( 1<=i<=(n-1) ) + x1
再由于n,m,ai均为常数,上述xi的表达式变量均为x1,但是这样依旧不够,仍旧需要转化成中位数模型
先抛开原题,考虑这样一个问题:
数轴上有n个点,现在求到这n个点的距离和最小的点在哪里。答案就是这些点坐标的中位数。证明笔者就不给出了,可以参考大白书,有兴趣的读者可以一试。
回到原题,我们将xi的表达式改写:
x1 = x1 - 0
x2 = x1 -(a1-m)
x3 = x1 -(a2+a1-2m)
x4 = x1 -(a3+a2+a1-3m)
……
别忘了我们xi表达的是金币转移的数量,即为正数,故所求需要加绝对值,那么 :
|x1| = |x1 - 0|
|x2| = |x1 -(a1-m)|
|x3| = |x1 -(a2+a1-2m)|
|x4| = |x1 -(a3+a2+a1-3m)|
这么一写,是不是就是上面说的中位数的模型了,其中0,(a1-m),(a2+a1-2m),(a3+a2+a1-3m)……不妨看成是数轴上一系列的点。x1即为需要求出的中位数。 求出中位数后,带入上式累加,即可求出最终的答案。
代码总览
#include <cstdio>
#include <algorithm>
#include <cmath>
#define nmax 1000005
#define ll long long
using namespace std;
ll a[nmax],c[nmax];
int main()
{
int n;
while(scanf("%d",&n) != EOF){
ll sum = 0;
for(int i = 0; i<n; ++i){scanf("%d",&a[i]);sum+=a[i];}
ll t = sum/n;c[0] = 0;
//ci 为对应的0,(a1-m),(a2+a1-2m),(a3+a2+a1-3m)……
for(int i = 1 ;i<n; ++i)
c[i] = c[i-1] + a[i] - t;
sort(c,c+n);
//pos为中位数
ll pos = c[n/2],ans = 0;
for(int i = 0; i<n;++i) ans+=fabs(pos-c[i]);
printf("%lld\n",ans);
}
return 0;
}
UVA.11300 Spreading the Wealth (思维题 中位数模型)的更多相关文章
- 数学/思维 UVA 11300 Spreading the Wealth
题目传送门 /* 假设x1为1号给n号的金币数(逆时针),下面类似 a[1] - x1 + x2 = m(平均数) 得x2 = x1 + m - a[1] = x1 - c1; //规定c1 = a[ ...
- UVa 11300 Spreading the Wealth(有钱同使)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New ...
- 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(递推,中位数)
Spreading the Wealth Problem A Communist regime is trying to redistribute wealth in a village. They ...
- UVA 11300 Spreading the Wealth (数学推导 中位数)
Spreading the Wealth Problem A Communist regime is trying to redistribute wealth in a village. They ...
- Math - Uva 11300 Spreading the Wealth
Spreading the Wealth Problem's Link ---------------------------------------------------------------- ...
- [ACM_几何] UVA 11300 Spreading the Wealth [分金币 左右给 最终相等 方程组 中位数]
Problem A Communist regime is trying to redistribute wealth in a village. They have have decided to ...
- 【思维】UVA 11300 Spreading the Wealth
题目大意 vjudge链接 有n个人围圆桌而坐,每个人有Ai个金币,每个人可以给左右相邻的人一些金币. 若使得最终所有人金币数相等,求最小金币转移数. 数据范围 n<1000001 样例输入 3 ...
随机推荐
- Qt-QML-Repeater-导航条
上篇文章中,我写了一个自己的Button,也就是美化了一下QML自带的Button 就是上面的这个,剩下的就是放三张图片在上面就可以了,当然了,这个Button在后期,还是会加入更让多的美化,比如,可 ...
- Sysbench安装步骤及详情
Sysbench安装步骤及详情 Sysbench是压力测试工具,可以测试系统的CPU,内存,I/O等,也可以用于数据库的性能测试 Sysbench安装步骤: 安装具体分为Ubuntu16.04和Cen ...
- Python汉诺塔问题递归算法与程序
汉诺塔问题: 问题来源:汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从上往下从小到大顺序摞着64片黄金圆盘.上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱 ...
- C++11 type_traits 之is_pointer,is_member_function_pointer源码分析
源码如下: template<typename> struct __is_pointer_helper : public false_type { }; template<typen ...
- 丑哭了CSDN。
真是不知道如何设置,忒,,,,不知如何表达.
- 【WXS全局对象】Global
Global对象的方法调用时,无需使用 Global.parseInt(...),而是直接使用 parseInt(...) 方法: 名称 说明 parseInt(string, radix) 解析一个 ...
- Spring Cloud(十一):服务网关 Zuul(过滤器)【Finchley 版】
Spring Cloud(十一):服务网关 Zuul(过滤器)[Finchley 版] 发表于 2018-04-23 | 更新于 2018-05-07 | 在上篇文章中我们了解了 Spring ...
- 【setUp-tearDown】线程组开始,结束各执行一次
使用setUp线程组的方式 ——> 开始 使用tearDown线程组 的方式 ——>结束
- 如何使用AEditor制作一个简单的H5交互页demo
转载自:http://www.alloyteam.com/2015/06/h5-jiao-hu-ye-bian-ji-qi-aeditor-jie-shao/ 本教程演示如何使用AEditor制作一个 ...
- day-15 用opencv怎么扫描图像,利用查找表和计时
一.本节知识预览 1. 怎样遍历图像的每一个像素点? 2. opencv图像矩阵怎么被存储的? 3. 怎样衡量我们算法的性能? 4. 什么是查表,为什么要使用它们? 二.什么是查表,为什么要使 ...