平分糖果——BZOJ 1045

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

不是圈的话,就像平分纸牌,加了个圈的话

假设平均数是x,且a1给an了k个(k<0说明是an给a1了k个),那么总代价就可以算出来:

令si=sum(a1..i)-ix,则总代价=sum|si-k|。易知k为中位数时此值最小。问题转化为求中位数……

View Code
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;

int a[1000009];
int s[1000009];

long long mabs(long long a)
{
if(a<0)a=-a;
return a;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
long long i,all=0,mid,temp;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
all+=a[i];
s[i]=all;
}
temp=all/n;
for(i=1;i<=n;i++)
{
s[i]-=temp*i;
}

sort(&s[1],&s[n+1]);
mid=s[(n+1)/2];
all=0;
for(i=1;i<=n;i++)
{
all+=mabs(s[i]-mid);
}

printf("%lld\n",all);
}

return 0;
}



原文地址:https://www.cnblogs.com/huhuuu/p/2339273.html