BZOJ 1045 [HAOI2008]糖果传递 ★(环形等分:中位数)
题意
有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。思路
假设平均数是x,且a1给an了k个(k<0说明是an给a1了-k个),那么总代价就可以算出来:an | |||
an+k | a1-k | a2 | |
代价:|k| | x | a1+a2-x-k | a3 |
代价:|a1-x-k| | x | a1+a2+a3-2x-k | |
代价:|a1+a2-2x-k| | x | ||
代价:|a1+a2+a3-3x-k| |
代码
[cpp] #include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <set> #include <stack> #include <queue> #define MID(x,y) ((x+y)/2) #define MEM(a,b) memset(a,b,sizeof(a)) #define REP(i, begin, end) for (int i = begin; i <= end; i ++) using namespace std; const int maxn = 1000005; int a[maxn]; long long sum[maxn], b[maxn]; int main(){ int n; scanf("%d", &n); sum[0] = 0; REP(i, 1, n){ scanf("%d", &a[i]); sum[i] = sum[i-1] + a[i]; } long long average = sum[n] / n; REP(i, 0, n-1){ b[i] = sum[i] - (i) * average; } sort(b, b+n); long long res = 0; REP(i, 0, n-1){ res += abs(b[i] - b[n/2]); } printf("%lld\n", res); return 0; } [/cpp]举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG