1045: [HAOI2008] 糖果传递

题目:传送门(双倍经验3293

题解:

   一开始想着DP贪心一顿乱搞,结果就GG了

十分感谢hzwer大佬写的毒瘤数论题解:

  首先,最终每个小朋友的糖果数量可以计算出来,等于糖果总数除以n,用ave表示。
  假设标号为i的小朋友开始有Ai颗糖果,Xi表示第i个小朋友给了第i-1个小朋友Xi颗糖果,如果Xi<0,说明第i-1个小朋友给了第i个小朋友Xi颗糖果,X1表示第一个小朋友给第n个小朋友的糖果数量。 所以最后的答案就是ans=|X1| + |X2| + |X3| + ……+ |Xn|。
  对于第一个小朋友,他给了第n个小朋友X1颗糖果,还剩A1-X1颗糖果;但因为第2个小朋友给了他X2颗糖果,所以最后还剩A1-X1+X2颗糖果。根据题意,最后的糖果数量等于ave,即得到了一个方程:A1-X1+X2=ave。
  同理,对于第2个小朋友,有A2-X2+X3=ave。最终,我们可以得到n个方程,一共有n个变量,但是因为从前n-1个方程可以推导出最后一个方程,所以实际上只有n-1个方程是有用的。
  尽管无法直接解出答案,但可以用X1表示出其他的Xi,那么本题就变成了单变量的极值问题。
  对于第1个小朋友,A1-X1+X2=ave  ->  X2=ave-A1+X1 = X1-C1(假设C1=A1-ave,下面类似)
  对于第2个小朋友,A2-X2+X3=ave  ->  X3=ave-A2+X2=2ave-A1-A2+X1=X1-C2
  对于第3个小朋友,A3-X3+X4=ave  ->  X4=ave-A3+X3=3ave-A1-A2-A3+X1=X1-C3……
  对于第n个小朋友,An-Xn+X1=ave。
    我们希望Xi的绝对值之和尽量小,即|X1| + |X1-C1| + |X1-C2| + ……+ |X1-Cn-1|要尽量小。注意到|X1-Ci|的几何意义是数轴上的点X1到Ci的距离,所以问题变成了:给定数轴上的n个点,找出一个到他们的距离之和尽量小的点,而这个点就是这些数中的中位数。
  
  这里给出一点小小的证明:

  数轴上任意找一个点,它左边有4个点,右边有2个点,把该点往左移动一点点,不要移动太多,以免碰到其他输入点。假设移动了d单位距离,则该点到左边4个点的距离各减少d,该点都右边2个点的距离各增加d,但总的来说,距离之和减少了2d。

  同理,该点的左边有2个点,右边有4个点时,类似,不过此时应该是向右移动。

  换句话说,只要该点的左右两边的输入点个数不一样多,就不是最优解。那什么情况下,左右点一样多勒?如果输入点有奇数个,则最优解应该是中间那个点即中位数。如果有偶数个,则可以位于最中间两个点的任意位置(还是中位数)。

代码:

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
int n;LL a[],c[],sum;
int main()
{
scanf("%d",&n);sum=;
for(int i=;i<=n;i++)scanf("%lld",&a[i]),sum+=a[i];sum/=n;
memset(c,,sizeof(c));for(int i=;i<=n;i++)c[i]=c[i-]+a[i]-sum;
sort(c+,c+n+);LL mid;
if(n&)mid=c[(n+)/];else mid=c[n/];
LL ans=;for(int i=;i<=n;i++)ans+=abs(c[i]-mid);
printf("%lld\n",ans);
return ;
}

bzoj1045: [HAOI2008] 糖果传递(数论)的更多相关文章

  1. 【bzoj1465/bzoj1045】糖果传递 数论

    题目描述 老师准备了一堆糖果, 恰好n个小朋友可以分到数目一样多的糖果. 老师要n个小朋友去拿糖果, 然后围着圆桌坐好, 第1个小朋友的左边是第n个小朋友, 其他第i个小朋友左边是第i-1个小朋友. ...

  2. bzoj3293 [Cqoi2011]分金币&&bzoj1045 [HAOI2008]糖果传递

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

  3. BZOJ1045 [HAOI2008] 糖果传递

    Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n<=987654321,表示小朋友的个数 ...

  4. [BZOJ1045] [HAOI2008] 糖果传递 (贪心)

    Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数n<=,表示小朋友的个数.接下来n行,每行 ...

  5. [BZOJ1045][HAOI2008]糖果传递 (环形均分纸牌)

    题意 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. 思路 把|s[i]-s[k]|求和即可,s[i]是A的前缀和 s[k]为s数组的中位数时,总值 ...

  6. BZOJ1045 HAOI2008糖果传递(贪心)

    显然最后每个小朋友所拥有的糖果数就是糖果数总和的平均数.设该平均数为t. 环的问题一般断成链,但这个题似乎没有什么很好的办法在枚举断点的时候快速算出答案(我甚至不知道会不会有断点) 于是我们假装把他断 ...

  7. BZOJ1045 [HAOI2008]糖果传递 && BZOJ3293 [Cqoi2011]分金币

    Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数nn<=1'000'000,表示小朋友的个 ...

  8. 【贪心】bzoj1045: [HAOI2008] 糖果传递

    很妙的贪心思考过程 Description 有n个小朋友坐成一圈,每人有ai个糖果.每人只能给左右两人传递糖果.每人每次传递一个糖果代价为1. Input 第一行一个正整数nn<=1'000'0 ...

  9. bzoj1045: [HAOI2008] 糖果传递(思维题)

    首先每个人一定分到的糖果都是所有糖果的平均数ave. 设第i个人给i-1个人Xi个糖果,则有Ai-Xi+X(i+1)=ave. 则A1-X1+X2=ave,A2-X2+X3=ave,A3-X3+X4= ...

随机推荐

  1. 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面

    题目:输入一个整数数组.实现一个函数来调整该数组中数字的顺序.使得全部奇数位于数组的前半部分.全部偶数位于数组的后半部分. 1.基本实现: 假设不考虑时间复杂度,最简单的思路应该是从头扫描这个数组,每 ...

  2. c# 无法加载xxx.dll 找不到指定的模块(如何指定文件夹)

    如果直接放在项目运行目录,例如bin/debug可以直接加载,但是这样比较乱. 如果在放debug里面的一个文件夹里面,有可能会报错“无法加载xxx.dll 找不到指定的模块”. 如果路径写成这样就会 ...

  3. DNS反射放大攻击分析——DNS反射放大攻击主要是利用DNS回复包比请求包大的特点,放大流量,伪造请求包的源IP地址为受害者IP,将应答包的流量引入受害的服务器

    DNS反射放大攻击分析 摘自:http://www.shaojike.com/2016/08/19/DNS%E6%94%BE%E5%A4%A7%E6%94%BB%E5%87%BB%E7%AE%80%E ...

  4. mahout demo——本质上是基于Hadoop的分步式算法实现,比如多节点的数据合并,数据排序,网路通信的效率,节点宕机重算,数据分步式存储

    摘自:http://blog.fens.me/mahout-recommendation-api/ 测试程序:RecommenderTest.java 测试数据集:item.csv 1,101,5.0 ...

  5. [IOI 1999] 花店橱窗布置

    [题目链接] https://www.luogu.org/problemnew/show/P1854v [算法] f[i][j]表示放了前i束花,第i束花放在第j个花瓶中,所能获得的最大美学值 由于要 ...

  6. windows2003安装

    产品密钥JCDPY-8M2V9-BR862-KH9XB-HJ3HMiis的i386文件夹http://pan.baidu.com/s/1dD0EY6twindows2003的iso映像http://p ...

  7. JQuery学习系列篇(一)

    jQuery是一套Javascript脚本库:注意jQuery是脚本库, 而不是脚本框架. "库"不等于"框架", 比如"System程序集" ...

  8. Asp.net Web Api中使用配置Unity

    第一步:建立web api,添加unity.webapi. 第二步:在添加了该引用之后,在App_Start中会自动生成UnityConfig.cs文件 第三步:添加数据做测试 第四步:展示效果

  9. linux下服务启动脚本

    #!/usr/bin/env python# -*- coding: utf-8 -*-# @File : deployment.py# @Author: Anthony.waa# @Date : 2 ...

  10. 限制input 内部字数

    当输入字数多于限定值后,输入框显示不出来多出的字符 对于input来说,innerHTML 不能查询和更改,只能用value 来 size 属性规定输入字段的宽度 size 属性定义的是可见的字符数 ...