【BZOJ 1045】 [HAOI2008] 糖果傳遞
阿新 • • 發佈:2018-03-07
lac efi source span 遞推 所有 ret clu long
顯然選擇所有這些點裏面的中位數就好。
(即ci的中位數
(ci可以觀察形式,用遞推的方法得到
【鏈接】 我是鏈接,點我呀:)
【題意】
在這裏輸入題意
【題解】
思路來自hzwer..
設xi表示第i個人往左傳遞了xi個糖果。
(如果小於0表示旁邊的人給他了糖果。
則ans=∑|xi|
最後所有人的糖果數都變成sum/n->avg
則
a1-x1+x2 = avg
a2-x2+x3= avg
...
然後可以用avg和x1來表示所有的x2...xn
比如
x2 = x1-(avg-a1)
x3 = x1-(2avg-a1-a2)
....
會發現x1右邊的式子都是常量。
且都是x1-ci的形式
那麽就相當於有n個點。
然後現在讓你選擇一個點x1.
使得∑|x1-ci|最小。
(即ci的中位數
(ci可以觀察形式,用遞推的方法得到
【代碼】
#include <bits/stdc++.h>
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define all(x) x.begin(),x.end()
#define pb push_back
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1
using namespace std;
const double pi = acos(-1);
const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};
const int N = 1e6;
int n;
int a[N+10],c[N+10];
int main(){
#ifdef LOCAL_DEFINE
freopen("rush_in.txt", "r", stdin);
#endif
scanf("%d",&n);
rep1(i,1 ,n)
scanf("%d",&a[i]);
LL sum = 0;
rep1(i,1,n) sum+=a[i];
sum/=n;
c[1] = sum-a[1];
rep1(i,2,n-1) c[i] = c[i-1] + sum-a[i];
c[n] = 0;
sort(c+1,c+1+n);
LL x1 = c[n/2+1];
sum = 0;
rep1(i,1,n)
sum+=abs(x1-c[i]);
printf("%lld\n",sum);
return 0;
}
【BZOJ 1045】 [HAOI2008] 糖果傳遞