bzoj 1045: [HAOI2008] 糖果传递

Description

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

solution

标签PJ的题目我不会写......
设平均值为M,\(M=ai-xi+x_{i+1}\) 即等于初始量加减往两边流通的量
易得 \(M=a1-x1+x2\) -> \(x2=x1+M-a1=x1-b2\)\(bi=ai-M+b_{i-1}\)
同理 \(x3=x2+M-a3\) -> \(x3=x1-b3\)
推出 \(xn=x1-bn\)
要求 $$\sum{abs(xi)}$$
即求 $$\sum{abs(x1-bi)}$$
这里 \(x1\) 是可以任意选取的,\(bi\) 为定值,所以目标变为求所有点到一个点的距离的最小值

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=1000005;
int n,a[N];ll tot=0,b[N];
void work()
{
   RG int i;
   scanf("%d",&n);
   for(i=1;i<=n;i++)scanf("%d",&a[i]),tot+=a[i];
   tot/=n;
   ll ans=0;
   for(i=1;i<=n;i++)b[i]=b[i-1]+a[i]-tot;
   sort(b+1,b+n+1);
   ll li=b[n>>1];
   for(i=1;i<=n;i++)ans+=abs(b[i]-li);
   printf("%lld\n",ans);
}

int main(){work();return 0;}

posted @ 2017-10-24 21:37  PIPIBoss  阅读(161)  评论(0编辑  收藏  举报