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;
}