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;}