題目大意
有n個小朋友坐成一圈,每人有a_i顆糖果。
每人只能給左右兩人傳遞糖果。
每人每次傳遞一顆糖果的代價爲1。
求使所有人獲得均等糖果的最小代價。
對於100%的數據,n<=10^6。
題目分析
有一..難。不要着急。
我搞明白了!
設x[i]表示i+1向i傳的糖果數,x[n]表示1向n傳的糖果數
a[1]+x[1]−x[n]=
a[2]+x[2]−x[1]=
a[3]+x[3]−x[2]=
⋯⋯⋯⋯
a[n−1]+x[n−1]−x[n−2]=把式子變形:
x[1]=−a[1]+x[n]
x[2]=−a[2]+x[1]=2∗−a[2]−a[1]+x[n]
x[3]=−a[3]+x[2]=3∗−a[3]−a[2]−a[1]+x[n]
⋯⋯⋯⋯
x[n−1]=−a[n−1]+x[n−2]=(n−1)∗−a[i]+x[n]
x[n]=n∗−a[i]+x[n]=0+x[n]設s[i]=a[j]−i∗,則:
ans=∑∣x[i]∣=∑∣s[i]−x[n] ∣
所以當x[n]爲{s[1],s[2],...,s[n]}的中位數時答案最小
以上摘自:https://www.cnblogs.com/CtrlCV/p/5626194.html 蒟蒻終於看懂了/哭/!!!
看懂了嗎???如果你暈了,估計是卡在s[i]那了吧。反正我剛開始是(我也太弱了吧)。
那我添油加醋(貌似是個貶義詞??)說點:(紅色的是新加的輔助理解)
設s[i]=a[j]−i∗:
x[1]=−a[1]+x[n]=x[n]-s[1]
x[2]=−a[2]+x[1]=2∗−a[2]−a[1]+x[n]=x[n]-s[2]
x[3]=−a[3]+x[2]=3∗−a[3]−a[2]−a[1]+x[n]=x[n]-s[3]
⋯⋯⋯⋯
x[n−1]=−a[n−1]+x[n−2]=(n−1)∗−a[i]+x[n]=x[n]-s[n-1]
x[n]=n∗−a[i]+x[n]=0+x[n]=x[n]-s[n](話說s[n]等於0這個不用說吧)
ans=∑∣x[i]∣=∑∣x[n]-s[i] ∣=∑∣s[i]−x[n] ∣
然後最後一句:所以當x[n]爲{s[1],s[2],...,s[n]}的中位數時答案最小
這個應該可以證明ba,但是我已經強調我蒟了(強行甩鍋),可以百度一下??
代碼
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long ave,x=0,ans=0;
long long a[1000010],s[1000010];
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);//每個人的初始糖果數
ave+=a[i];//平均數ave
}
ave/=n; a[n+1]=a[1];
for(int i=1;i<=n;i++)
{
x+=a[i];
s[i]=x-i*ave;
}
sort(s+1,s+1+n);
long long mid=s[n/2+1];//中位數
for(int i=1;i<=n;i++) ans+=abs(s[i]-mid);
printf("%lld",ans);
return 0;
}
記得最愛你的long long