今天接觸到這道水題,才發現……我好菜啊t^t
廢話少說,革命尚未成功,同志們還需努力啊!
這道題用到了字首和、歸納法、貪心思想。
看到題我們可以馬上想到求平均值,之後嘛……
乙個乙個數唄(he~tui)t^t進入正題。 分析
首先設x[i]表示i+1向i傳的糖果數(可以為正也可以為負),特殊的x[n]表示1向n傳遞的糖果數
我們用陣列儲存下資料a[i],求得平均值為a。
我們可以得到:
a[1]+x[1]-x[n]=a(這個式子是第乙個孩子加上第二個孩子給的糖果減去給第n個孩子的糖果就是平均值)
a[2]+x[2]-x[1]=a
……a[n-1]+x[n-1]-x[n-2]=a
a[n]+x[n]-x[n-1]=a(其實這個式子是沒用的)
既然要求最少的傳遞的次數,就相當於:ans=x[1]+x[2]+x[3]……+x[n];
x[1]=a-a[1]+x[n]
x[2]=a-a[2]+x[1]=2*a-a[2]-a[1]+x[n]
…x[n-1]=a-a[n-1]+x[n-2]=(n-1)a-a[n-1]-a[n-2]…-a[1]+x[n];
設s[i]=(a[1]+a[2]…+a[i])-ia;所以x[i]=s[i]-x[n];
這是我們還有乙個未知數x[n];那它又有什麼用呢?別急接著看;
ans=|x[1]|+|x[2]|+…+|x[n]|=(s[1]-x[n])+(s[2]-x[n])…+(s[n]-x[n]);
既然是求最小值那就相當於在數軸上有n個點,當x[n]是多少時最小,當然是中位數的時候了。
求出s[i]的中位數,當x[n]為中位數時,最小。
**
#includeusing namespace std;
long long int a[1000005],s[1000005];
int main()
sum/=n;
for(i=1;i<=n;i++)
s[i]=s[i-1]+sum-a[i];
sort(s+1,s+n+1);
mid=s[(n+1)/2];
for(i=1;i<=n;i++)
ans+=abs(s[i]-mid);
printf("%lld\n",ans);
return 0;
}
問題 K 貪心 糖果傳遞
題目描述 有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞乙個糖果代價為1。輸入第一行乙個正整數nn 1 000 000,表示小朋友的個數 接下來n行,每行乙個整數ai,表示第i個小朋友得到的糖果的顆數 輸出求使所有人獲得均等糖果的最小代價。複製樣例資料 412 54...
HAOI2008 糖果傳遞
洛谷題面 和題解差不多,加了點證明。有 n 個小朋友坐成一圈,每人有 a i 個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞乙個糖果代價為 1 設 e 表示所有小朋友糖果數量的平均數,因為所有小朋友糖果總數不會變,所以最後每個人的糖果數都會變成平均數。設 num i 表示第 i 個小朋友往左傳的糖...
HDU 1034 傳遞糖果 模擬
題意是一群孩子圍成乙個圈,每個人把手中的糖果分一半給右邊的人,若分過之後手中的糖果數是奇數,則由老師提供一顆糖果給他,問這樣傳遞多少圈所有人的糖果數都能相等,最終每人手裡的糖果數是多少。由於題中已經解釋了結果是有限的數,那麼就直接模擬,要注意分的時候是從前面的人往後面傳遞。如下 1 include ...