UVA - 11300 Spreading the Wealth

【题目描述】

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

【输入格式】

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

【输出格式】

对于每组数据,输出被转手的金币的数量的最小值。输入保证这个值在 64位无符号整数的范围之内。

【Sample】

Input

3
100
100
100
4
1
2
5
4

Output

0
4

【Solution】

这是一道数学题

根据题意

每个人都可以给两边人传递硬币

为了简化问题

我们定向每个人i只能给下一个人x[i]枚硬币

那么我们的答案就是求\(|x_1| + |x_2| + ... + |x_n|\)的最小值

假设最终每个人分到num枚硬币

那么当前第i个人的情况是

a[i] - x[i] + x[i + 1] = num;

接下来就是推导式子

\(x_{i+1} = num - a_i + x_i\)

\(x_2 = num - a_1 + x_1\)

\(x_3 = num - a_2 + x_2\)

联立上述两个式子得到

\(x_2 = x_1 - (a_1 - num)\);

\(x_3 = x_2 - (a_1 + a_2 - 2 * num)\)

同理我们可以写出\(1\) ~ \(n\)所有的项数

所有的式子相加可以得到

$x_i = x_1 - $ \(\sum_{i = 1}^{n - 1} a_j - (n - 1) * m\)

由此可见,我们要求得答案只与\(x_1\)有关

拿一个\(tmp_i\)表示后面的一大坨\(\sum_{i = 1}^{n - 1} a_j - (n - 1) * m\)

我们的答案的表达式为

\(|x_1| + |x_2| + ... + |x_n| = |x_1| + |x_1 - tmp_2| + |x_1- tmp_3| + ... + |x_1- tmp_n|\)

根据这是一道数学题

不难想到

上述等式右边表示\(x _ 1\)到\(tmp_1\)~\(tmp_n\)的距离之和

显然,当\(x_1\)为集合$ {tmp_n} $的中位数时

该式子取得最小值

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define int long long
using namespace std; inline int read(){
int x = 0, w = 1;
char ch = getchar();
for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return x * w;
} const int maxn = 1000010;
int a[maxn], tmp[maxn];
int num, n; signed main(){
while(scanf("%lld", &n) != EOF){
memset(a, 0, sizeof a);
memset(tmp, 0, sizeof tmp);
int ans = 0;
int sum = 0;
for(int i = 1; i <= n ;i++){
a[i] = read();
sum += a[i];
}
num = sum / n;
tmp[1] = 0;
for(int i = 1; i < n; i++){
tmp[i + 1] = num - a[i] + tmp[i];
}
sort(tmp + 1, tmp + 1 + n);
int x = tmp[n / 2];
for(int i = 1; i <= n; i++){
ans += abs(x - tmp[i]);
}
cout << ans << endl;
}
return 0;
}

UVA - 11300 Spreading the Wealth(数学题)的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. Math - Uva 11300 Spreading the Wealth

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

  7. UVA 11300 Spreading the Wealth (数学推导 中位数)

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

  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 个人,每个人都有一定数量的金币,金币总数能够被 n 整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值,比如 n = 4, ...

随机推荐

  1. java实现第五届蓝桥杯神奇算式

    神奇算式 题目描述 由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成. 比如: 210 x 6 = 1260 8 x 473 = 3784 27 x 81 = 2187 都符合要求 ...

  2. pi-star 升级固件命令

    单天线热点: sudo pistar-mmdvmhshatflash hs_hat 双天线热点: sudo pistar-mmdvmhshatflash hs_dual_hat 命令: wget ht ...

  3. 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)

    系列文章 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来 ...

  4. C++拷贝构造函数被调用的时机

    拷贝构造函数调用的几种情况: 当用类的一个对象去初始化该类的另一个对象(或引用)时系统自动调用拷贝构造函数实现拷贝赋值. 若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数.( ...

  5. 读懂操作系统之缓存原理(cache)(三)

    前言 本节内容计划是讲解TLB与高速缓存的关系,但是在涉及高速缓的前提是我们必须要了解操作系统缓存原理,所以提前先详细了解下缓存原理,我们依然是采取循序渐进的方式来解答缓存原理,若有叙述不当之处,还请 ...

  6. Java基础?看完以后再也不惧怕面试了

    前言 这篇文章主要是Java基础部分,主要分为3个部分:Java集合.Java多线.JVM:这些东西帮助我面试成功率提升了很多.后面还有中间件Spring.Redis.RocketMQ等等吧,祝愿大家 ...

  7. 04-Python基础3

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  8. 深度学习在高德ETA应用的探索与实践

    1.导读 驾车导航是数字地图的核心用户场景,用户在进行导航规划时,高德地图会提供给用户3条路线选择,由用户根据自身情况来决定按照哪条路线行驶. 同时各路线的ETA(estimated time of ...

  9. python模拟网站登陆-滑动验证码

    普通滑动验证 以http://admin.emaotai.cn/login.aspx为例这类验证码只需要我们将滑块拖动指定位置,处理起来比较简单.拖动之前需要先将滚动条滚动到指定元素位置. impor ...

  10. 基础拾遗---委托,匿名函数,lambda

    前言: C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针.委托是存有对某个方法的引用的一种引用类型变量.引用可在运行时被改变.委托(Delegate)特别用于实现事件和回调方法. ...