bzoj 1045: [HAOI2008] 糖果傳遞

Description

有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞一個糖果代價爲1。

解:

1、設X[i]爲 第i個人向第i+1個人傳遞的紙牌數量  (signed)

那麼ans==sigma(abs( X[i]  ));

我們可知 a[i]+X[i-1]-X[i]=ave;----->X[i]==a[i]-ave+X[i-1];

那麼X[1]==a[1]-ave+X[n] (X[1-1]  相當於向前找 (因爲是環)所以是n)

      X[2]==a[2]-ave+X[1]==a[1]+a[2]-2*ave+X[n];

----->X[i]==sigma(a[i]-ave)+X[n]

另sigma(a[i]-ave)爲 S[i]

ans==sigma(abs( S[i]+X[n]  ))===sigma( abs( -S[i]-X[n] )   );

所以問題轉化爲找一個X[n]使得ans最小------>經典中位數問題。

#include <bits/stdc++.h>
using namespace std;
long long a[1000005], s[1000005];
#define ll long long
#define en '\n'
signed  main()
{
#define int register int
    int n;
    ll ave=0,ans=0;scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);ave+=a[i];
    }ave/=n;
    for(int i=1;i<=n;i++)
        s[i]=s[i-1]+ave-a[i];
        sort(s+1,s+1+n);
    for(int i=1;i<=n;i++){
        ans+=abs(s[i]-s[n>>1]);
    }cout<<ans<<en;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章