bzoj 1045: [HAOI2008] 糖果传递 (数学相关)

来源:互联网 发布:网络层有哪些协议 编辑:程序博客网 时间:2024/06/05 03:17

题目描述

传送门

题目大意: 有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。求使所有人获得均等糖果的最小代价。

题解

xi表i给i+1传递的糖果的数量
那么我们可以得到n个方程
xnx1=a¯a1
x1x2=a¯a2
x2x3=a¯a3

xn1xn=a¯an
那么对于方程做前缀和就能得到n个新的方程
xnxi=ij=1a¯aj
对于上面的方程进行变形,就能表示出xi
xi=xnij=1a¯aj
我们的目标就是要最小化ans=ni=1|xi|=ni=1(xnij=1a¯aj)
对于xn的取值,可以是不超过总和的任意值,显然所有的前缀和一定都在合法的范围之内。
那么我们只要让xn取到xnij=1a¯aj中的中位数即可。

代码

#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<cmath>#define N 1000003#define LL long long using namespace std;LL a[N],sum;int n;int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++) scanf("%lld",&a[i]),sum+=a[i];    sum/=n;    a[1]=sum-a[1];    for (int i=2;i<=n;i++){        int t=sum-a[i];        a[i]=a[i-1]+t;    }    sort(a+1,a+n+1);    LL t=a[n/2+1]; LL ans=0;    for (int i=1;i<=n;i++) ans+=abs(t-a[i]);    printf("%lld\n",ans);}
0 0
原创粉丝点击