BZOJ 1045: [HAOI2008] 糖果傳遞 數學,亂搞
Description
有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞一個糖果代價為1。
Input
第一行一個正整數n<=987654321,表示小朋友的個數.接下來n行,每行一個整數ai,表示第i個小朋友得到的
糖果的顆數.
Output
求使所有人獲得均等糖果的最小代價。
Sample Input
4
1
2
5
4
Sample Output
4
解題方法: 設i順時針傳給下一個人的數量為xi,目標平均值值為ave。則目標就是讓ai−xi+x(i-1)−1=ave的前提下最小化。
可以構造出
a1−x1+x2=ave
a2−x2+x3=ave
a1−x3+x4=ave
…..
an−xn+x1=ave
這個方程組有n個方程和n個變數,但顯然,最後一個方程式無意義。
於是考慮:
a1−x1+x2=ave⟹x2=ave+x1−a1
a2−x2+x3=ave⟹x3=ave+x2−a2=2×ave−a1−a2+x1
a3−x3+x4=ave⟹x4=3×ave−a1−a2−a3+x1
…
記c[i]=(sigma(a[j]),j從到i)-i*ave
所以:
x2=x1-c1
x3=x1-c2
….
我們希望Xi的絕對值之和儘量小,即|x1| + |x1-c1| + |x1-c2| + ……+ |x1-c(n-1)|要儘量小。注意到|x1-ci|的幾何意義是數軸上的點x1到xi的距離,所以問題變成了:給定數軸上的n個點,找出一個到他們的距離之和儘量小的點,而這個點就是這些數中的中位數,證明略。上面的c是直接替換之後的結果,也是下面程式碼裡面的c,畫一下就明白了。(0,c1,c2,c3”’,c[n-1])的中位數。
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int a[N], c[N];
int n;
int main(){
scanf("%d", &n);
long long ave = 0;
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
ave += a[i];
}
ave /= n;
for(int i = 2; i <= n; i++){
c[i] = c[i-1] + a[i] - ave;
}
sort(c + 1, c + n + 1);
long long ans = 0;
int j = (n + 1) / 2;
for(int i = 1; i <= n; i++){
ans += abs(c[i] - c[j]);
}
printf("%lld\n", ans);
return 0;
}
相關文章
- bzoj1054: [HAOI2008]移動玩具(寬搜)
- Shell學習【引數傳遞】
- BZOJ1044: [HAOI2008]木棍分割(dp 單調佇列)佇列
- 引數傳遞
- Bitset 亂搞字串匹配字串匹配
- JS的方法引數傳遞(按值傳遞)JS
- bzoj4448: [Scoi2015]情報傳遞(主席樹+Lca)
- Mybatis引數傳遞MyBatis
- 引數傳遞方式必須是const引用傳遞
- shell (3)指令碼引數傳遞與數學運算指令碼
- Flutter:學會在頁面間傳遞引數Flutter
- Shell自學二(引數傳遞和陣列)陣列
- React事件傳遞引數React事件
- 路由元件傳遞引數路由元件
- 面試官問:Go 中的引數傳遞是值傳遞還是引用傳遞?面試Go
- 深入學習js之——引數按值傳遞#9JS
- [技巧] 亂搞技巧 長期更新
- linux中main引數傳遞LinuxAI
- 利用閉包傳遞引數
- JavaScript函式傳遞引數JavaScript函式
- out,ref,params引數傳遞
- 請求引數的傳遞
- 函式的引數傳遞函式
- t-on-click 傳遞引數
- 向檢視傳遞變數變數
- Python的函式引數傳遞:傳值?引用?Python函式
- 函式作為引數傳遞函式
- C++引數的傳遞方式C++
- [Python] 傳遞引數前面的*或**Python
- 引數傳遞機制之JWTJWT
- JAVA基礎之-引數傳遞Java
- 函式引數傳遞及返回函式
- Python怎麼傳遞不定引數Python
- 值傳遞和引用傳遞
- 迭代與遞迴--你被遞迴搞暈過嗎?遞迴
- Go語言引數傳遞是傳值?還是傳引用 ?Go
- Python引數傳遞,既不是傳值也不是傳引用Python
- 引數的定義和引數的傳遞
- Vue3學習(十九) - 使用Vue完成頁面引數傳遞Vue