题目链接:https://vjudge.net/problem/UVA-11300

这道题的思路太神了,但很难想到是贪心。

用M表示每个人最终拥有的金币数。

首先假设有四个人。假设1号给2号3枚,2号又给1号5枚,那么实际上1号并没有给2号,而2号给了1号2枚。这样设$x_2$表示2号给了1号$x_2$枚。若$x_2<0$,那么就表示1号给了2号$-x_2$枚。这样我们就相当于在1号和2号之间连了一条边,表示1号2号之间硬币关系(注意是环形,所以$x_1$表示1号和4号之间的硬币关系)。

假设1号原来有$A_1$枚硬币,那么根据1号给了4号$x_1$枚,收到了$x_2$枚硬币,所以现在1号手中有$A_1+x_2-x_1$枚。根据开始的M,我们可以得到:$M=A_1+x_2-x_1$。同理,我们可以得到其他的方程。

得到n-1个方程之后,可以尝试用$x_1$表示其他的$x_i$:

对于第1个人:$M=A_1+x_2-x_1$ --> $x_2=M-A_1+x_1=x_1-C_1$(规定$C_1=A_1-M_1$);

对于第2个人:$M=A_2+x_3-x_2$ --> $x_3=M-A_2+x_2=M-A_2+(M-A_1+x_1)=2\times M-A_1-A_2+x_1=x_1-C_2$

.....

然而对于第n个人,这个式子是多余的——关于n的两个x,已在n-1和1中计算了。

现在我们希望所有$x_i$的绝对值要尽可能地小,即$|x_1|+|x_1-C_1|+\cdots +|x_1-C_{n-1}|$的最小,而它的几何意义便是在数轴上找一个点使得这个点到所有C的距离最短。我们会发现这个点便是这些数的中位数(奇偶都是)。

注意一些边界问题..

(详细证明见 蓝书P5)

AC代码:

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm> using namespace std; const int maxn=; int n;
long long mid,ans,sum,M;
long long A[maxn],C[maxn]; inline void init(){
memset(A,,sizeof(A));
sum=ans=;
} int main(){
while(scanf("%d",&n)!=EOF){
init();
for(int i=;i<=n;i++){
scanf("%lld",&A[i]);
sum+=A[i];
}
M=sum/n;
for(int i=;i<n;i++) C[i]=C[i-]+A[i]-M;
sort(C,C+n);
mid=C[n/];
for(int i=;i<n;i++) ans+=abs(C[i]-mid);
printf("%lld\n",ans);
}
return ;
}

AC代码

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(数学题)

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

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

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

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

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

  8. Math - Uva 11300 Spreading the Wealth

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

  9. [ACM_几何] UVA 11300 Spreading the Wealth [分金币 左右给 最终相等 方程组 中位数]

    Problem A Communist regime is trying to redistribute wealth in a village. They have have decided to ...

随机推荐

  1. PCB主线布线规范—高速线之DDR2

    一.DDR2时钟线走线规则a)时钟线包括 MEM_CLKOUT#0.MEM_CLKOUT0.MEM_CLKOUT#1.MEM_CLKOUT1,MEM_CLKOUT#2.MEM_CLKOUT2: MEM ...

  2. 基于Android的在线播放器系统的设计与实现

    文章结构: 1 引言 1.1系统的研究背景 现在的时代是互联网的时代,互联网高速发展的同时,无线网络也接入了互联网.社会的各个领域都已经被无线网络渗透.小的比如手机,电脑,电视.大的比如灯光系统,智能 ...

  3. JS高级---总结apply和call方法的使用

    apply和call的使用方法 apply的使用语法   函数名字.apply(对象,[参数1,参数2,...]); 方法名字.apply(对象,[参数1,参数2,...]);   call的使用语法 ...

  4. python网络编程(通过tcp或者udp协议通信)

    1.基于tcp协议传送文件: 客户端: import socketimport osimport jsonimport structclient = socket.socket()client.con ...

  5. Java-POJ1003-Hangover

    题目大意: 给出一个浮点数a,求出使得 不等式 1/2 + 1/3 + ... + 1/(n+1) ≥ a 成立的最小值 大水题,由于数据范围小,给出了确认上界5.20,满足二分答案 但是我懒啊,直接 ...

  6. rpm命令怎么指定安装位置

    rpm   -ivh    --prefix=路径      FILE.rpm

  7. 051_switch语句的使用 052_while循环详解 053_for循环详解_dowhile简介 054_嵌套循环_循环相关练习

    051_switch语句的使用 package testmode2;/** * 测试switch语句 * 遇到多值判断的时候,使用switch.当然,switch完全可以使用ifelseifelse代 ...

  8. 深入 js 深拷贝对象

    前言 对象是 JS 中基本类型之一,而且和原型链.数组等知识息息相关.不管是面试中,还是实际开发中我们都会碰见深拷贝对象的问题. 顾名思义,深拷贝就是完完整整的将一个对象从内存中拷贝一份出来.所以无论 ...

  9. ansible playbook详解

    ansible playbook是由yml语法书写,结构清晰,可读性强,所以必须掌握yml基础语法 语法 描述 缩进 YAML使用固定的缩进风格表示层级结构,每个缩进由两个空格组成,不能使用tabs键 ...

  10. fader

    fader在音频处理中是比较基础的处理.通常用于平滑的调节音量,或是音频的渐入和渐出效果. 比较常见的fader有line和cubic线型的fader. line fader即fader的渐变过程是线 ...