zoukankan      html  css  js  c++  java
  • [HAOI2008]糖果传递

    题目描述

    有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。

    输入输出格式

    输入格式:

    小朋友个数n 下面n行 ai

    输出格式:

    求使所有人获得均等糖果的最小代价。

    输入输出样例

    输入样例#1: 复制
    4
    1
    2
    5
    4
    输出样例#1: 复制
    4

    说明

    对于100%的数据 n≤106nle 10^6n106

    首先每个人最后的糖果数是可以计算出来的,我们记其为$M$。
    假设有$4$个人,编号$1$~$4$,第$i$个人初始糖果数量为$A_i$,设$1->4$糖果数为$x_1$(符号代表给出还是收入),那么我们对于标号为$1$的人很容易得到一个等式$M=A_1-x_1+x_2$。
    对于所有人我们都可以得到这样的一个等式,一共有$n$个变量,但可惜我们发现其实有效的等式只有只有$n-1$个(因为任意$n-1$个等式都可以推出剩下的一个等式)。
    我们无法求出答案,但我们可以试着用一个变量表示其他的变量,以$x_1$为例;
    对于第一个人,$A_1-x_1+x_2=M => x_2=M-A_1+x_1=x_1-C_1$(令$C_1=A_1-M$)
    对于第二个人,$A_2-x_2+x_3=M => x_3=M-A_2+x_2=2M-A_1-A_2+x_1=x_1-C_2$(令$C_2=C_1+A_2-M$)
    ……
    对于第$n$个人,$A_n-x_n+x_1=M$,这个是多余的,舍去。
    依题,我们要求$$sum_{i=1}^N Abs(x_i)$$
    对于刚才的推导,就是$$sum_{i=1}^N Abs(x_1-C_i)$$
    转化为数学模型就是数轴上所有点到一个点的距离。
    那么原题就是找到一个点,使得所有点到其距离和最短,显然找到一个中间点即可。

    附上巨佬的原文链接http://www.cnblogs.com/NaVi-Awson/p/7520039.html

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 long long a[1000001],c[1000001],n,ans,sum,m;
     7 int main()
     8 {int i;
     9   cin>>n;
    10   for (i=1;i<=n;i++)
    11     scanf("%lld",&a[i]),sum+=a[i];
    12   m=sum/n;
    13   for (i=1;i<=n;i++)
    14     c[i]=a[i]+c[i-1]-m;
    15   sort(c+1,c+n+1);
    16   long long pos=c[n/2];
    17   for (i=1;i<=n;i++)
    18     ans+=abs(c[i]-pos);
    19   cout<<ans;
    20 }
  • 相关阅读:
    一篇文章让你了解GC垃圾回收器
    使用SpringBoot整合ssm项目
    SpringBoot项目集成Hystrix
    50个简单易懂的经济学定律
    使用POI导出EXCEL工具类并解决导出数据量大的问题
    数据库事务的四大特性以及四种隔离级别
    简单了解Redis
    如何更规范化的编写JAVA 代码
    如何在Linux服务器上部署Mysql
    常见的数据库函数,关键字整理
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7724396.html
Copyright © 2011-2022 走看看