博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 11300 Spreading the Wealth
阅读量:6223 次
发布时间:2019-06-21

本文共 2962 字,大约阅读时间需要 9 分钟。

Description

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.

Input

There is a number of inputs. Each input begins with \(n (n \le 1000000)\), 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.

Output

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

Sample Input

310010010041254

Sample Output

04

Solution

考虑相邻的两个人\(A\)\(B\),或者\(A\)\(B\)金币,或者\(B\)\(A\)金币,所以设\(x_{i}\)为第\(i\)个人给第\(i - 1\)个人的金币数量(\(x_{1}\)为第\(1\)个人给第\(n\)个人的金币数量),\(x_{i} \ge 0\)表示第\(i\)个人给第\(i - 1\)个人金币,\(x_{i} \lt 0\)表示第\(i-1\)个人给第\(i\)个人金币,\(c = \frac{\sum_{i=1}^{n}a_{i}}{n}\)为最终每个人手中的金币数量,由此我们可以得到方程组:

\[ \begin{align} a_{1} - x_{1} + x_{2} &= c\\\ a_{2} - x_{2} + x_{3} &= c\\\ \dots\\\ a_{n} - x_{n} + x_{1} &= c\\\ \end{align} \]
进一步可以得到:
\[ \begin{align} x_{2} &= x_{1} - \left(a_{1} - c\right)\\\ x_{3} &= x_{2} - \left(a_{2} - c\right) = x_{1} - \left(a_{1} - c\right) - (a_{2} - c)\\\ \dots\\\ x_{n} &= x_{1} - \left(a_{1} - c\right) - (a_{2} - c) - \cdots - (a_{n-1} - c)\\\ \end{align} \]
我们不妨令:
\[ \begin{align} d_{1} &= 0\\\ d_{2} &= \left(a_{1} - c\right)\\\ d_{3} &= \left(a_{1} - c\right) + \left(a_{2} - c\right)\\\ \dots\\\ d_{n} &= \left(a_{1} - c\right) + \left(a_{2} - c\right) + \cdots + \left(a_{n-1} - c\right)\\\ \end{align} \]

我们的目标是最小化\(\left|x_{1}\right| + \left|x_{2}\right| + \cdots \left|x_{n}\right|=\left|x_{1} - d_{1}\right| + \left|x_{1} - d_{2}\right| + \cdots \left|x_{1} - d_{n}\right|\),这相当于已知\(x\)轴上的\(n\)个点,我们要找到一个点\(x_{1}\),使得\(x_{1}\)到各个点的距离之和最小,不难证明,当\(x_{1}\)为这\(n\)个数中的中位数时,可以得到最优解。

#include 
using namespace std;typedef long long ll;const int maxn = 1000011;ll a[maxn], d[maxn];int main() { int n; while (scanf("%d", &n) == 1) { ll sum = 0; for (int i = 1; i <= n; ++i) { scanf("%lld", a + i); sum += a[i]; } ll c = sum / (ll)n; for (int i = 1; i < n; ++i) { d[i] = d[i - 1] + a[i] - c; } d[n] = 0; sort(d + 1, d + 1 + n); int p = (n + 1) / 2; ll v = d[p], ans = 0; for (int i = 1; i < p; ++i) ans += v - d[i]; for (int i = p + 1; i <= n; ++i) ans += d[i] - v; printf("%lld\n", ans); } return 0;}

转载于:https://www.cnblogs.com/hitgxz/p/9977673.html

你可能感兴趣的文章
jquery-event01
查看>>
9,mysql触发器
查看>>
在交换机上拒绝非法的DHCP服务器分配IP地址
查看>>
解决ezSQL编码问题
查看>>
[转]如何用Jmeter做压力测试
查看>>
跨站点如何快速部署DC
查看>>
C#修改目录和文件权限
查看>>
EL表达式
查看>>
深入浅出Hadoop Mahout数据挖掘实战(算法分析、项目实战、中文分词技术)
查看>>
UbuntuServer 12.04安装记录(二):svn服务的创建
查看>>
谈谈最近深圳找工作经历
查看>>
vSphere 5.0 存储特点—简介
查看>>
android 自定义全局未处理异常捕获器
查看>>
12 月29日导入数据库 文件
查看>>
elasticsearch安装教程
查看>>
Windows Server 2008 R2 自定义桌面
查看>>
MYSQL定时任务
查看>>
It’s All Over
查看>>
Gradle-user guide-第6章 构建脚本基础(译)
查看>>
NO.5 选择适合您的禅道项目管理软件安装方法
查看>>