Uva 11300 Spreading the Wealth(贪心)
题目链接: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(贪心)的更多相关文章
- 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个人,每个人手中有a[i]个数的金币,每个人能给其左右相邻的人金币,现在要求你安排传递金币的方案,使得每个人 ...
- 数学/思维 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(数学题)
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 ...
随机推荐
- echarts 设置默认选中,单选
默认选中 和 不选中 传送门
- C#获取当前不同网卡对应的iP
C#获取当前不同网卡对应的iP: public string GetLocalIP() { IPAddress localIp = null; try { IPAddress[] ipArray; i ...
- 新建表需要原表的数据,mysql 如何把查询到的结果插入到新表中
项目运用情景:新建表需要原表的数据 1. 如果两张张表(导出表和目标表)的字段一致,并且希望插入全部数据,可以用这种方法: INSERT INTO 目标表 SELECT * FROM 来源表 ...
- Java之字符串输入next()与nextLine()
next():一定要读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键.Tab键或Enter键等结束符,next()方法会自动将其去掉: 只有在输入有效字符之后,next( ...
- 命令行(二):Anaconda3
1,进入base虚拟环境 $:activate 2,创建虚拟环境(自动下载Python3最新版本) $:conda create -n <virtual_name> python= 3,切 ...
- codeforces Codeforces Round #597 (Div. 2) B. Restricted RPS 暴力模拟
#include <bits/stdc++.h> using namespace std; typedef long long ll; ]; ]; int main() { int t; ...
- Java爬虫学习(2)之用对象保存文件demo(1)
package com.mieba.spider; import java.util.ArrayList; import java.util.List; import java.util.Vector ...
- instGroup/constraint/Gcell/busguide/netgroup/Bump
1. instGroup Instance group.中文名例化单元组.Instance group可以用来group一些instances, 在做placement时,如果你希望一些instanc ...
- ios 下 select和option 无法隐藏指定元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- mybatis--一对多关联
今天来介绍mybatis的一对多关联 (1)首先创建数据库mybatisonetomany,并创建数据库表post和user,并向其中插入一定的数据: create database mybatiso ...