[BZOJ1045] [HAOI2008] 糖果传递 (贪心)
Posted CtrlCV
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ1045] [HAOI2008] 糖果传递 (贪心)相关的知识,希望对你有一定的参考价值。
Description
有n个小朋友坐成一圈,每人有ai个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为1。
Input
第一行一个正整数n<=1000000,表示小朋友的个数.接下来n行,每行一个整数ai,表示第i个小朋友得到的
糖果的颗数.
Output
求使所有人获得均等糖果的最小代价。
Sample Input
1
2
5
4
Sample Output
HINT
Source
Solution
设$x[i]$表示$i+1$向$i$传的糖果数,$x[n]$表示$1$向$n$传的糖果数
$a[1]+x[1]-x[n]=\\overline a$
$a[2]+x[2]-x[1]=\\overline a$
$a[3]+x[3]-x[2]=\\overline a$
$\\cdots \\cdots$
$a[n-1]+x[n-1]-x[n-2]=\\overline a$
$a[n]+x[n]-x[n-1]=\\overline a$(其实这个式子没用)
把式子变形:
$x[1]=\\overline a-a[1]+x[n]$
$x[2]=\\overline a-a[2]+x[1]=2*\\overline a-a[2]-a[1]+x[n]$
$x[3]=\\overline a-a[3]+x[2]=3*\\overline a-a[3]-a[2]-a[1]+x[n]$
$\\cdots \\cdots$
$x[n-1]=\\overline a-a[n-1]+x[n-2]=(n-1)*\\overline a-\\sum_{i=1}^{n-1}a[i]+x[n]$
$x[n]=n*\\overline a-\\sum_{i=1}^{n}a[i]+x[n]=0+x[n]$
设$\\displaystyle s[i]=\\sum_{j=1}^{i}a[j]-i*\\overline a$,则:
$\\displaystyle ans=\\sum\\mid x[i]\\mid\\ =\\sum\\mid s[i]-x[n]\\ \\mid$
所以当$x[n]$为$\\big\\{s[1], s[2], ..., s[n]\\big\\}$的中位数时答案最小
题面数据范围是在搞笑的,糖果数在$int$范围,答案在$long\\ long$范围,剩下的就没什么难度了
1 #include <bits/stdc++.h> 2 using namespace std; 3 long long a[1000005], s[1000005]; 4 int main() 5 { 6 int n; 7 long long ave = 0, ans = 0; 8 scanf("%d", &n); 9 for(int i = 1; i <= n; ++i) 10 scanf("%lld", a + i); 11 for(int i = 1; i <= n; ++i) 12 ave += a[i]; 13 ave /= n; 14 for(int i = 1; i <= n; ++i) 15 s[i] = s[i - 1] + a[i] - ave; 16 sort(s + 1, s + n + 1); 17 for(int i = 1; i < n / 2 + 1; ++i) 18 ans += s[n / 2 + 1] - s[i]; 19 for(int i = n / 2 + 1; i <= n; ++i) 20 ans += s[i] - s[n / 2 + 1]; 21 printf("%lld\\n", ans); 22 return 0; 23 }
接下来是有爱的双倍经验时间:$BZOJ3293$
以上是关于[BZOJ1045] [HAOI2008] 糖果传递 (贪心)的主要内容,如果未能解决你的问题,请参考以下文章