BZOJ1045 糖果傳遞(基於貪心的數學題)

2021-08-22 07:23:01 字數 1879 閱讀 6372

點此看題面

大致題意:有n

nn個小朋友坐成一圈,每人有a[i

]a[i]

a[i]

個糖果。每人只能給左右兩人傳遞糖果,傳遞乙個糖果代價為1,求使所有人獲得均等糖果的最小代價。

數學轉換

這題其實是一道帶有濃厚數學色彩的貪心題。

我們可以先用sum

sumsu

m來統計a[i

]a[i]

a[i]

之和,然後將sum

sumsu

m除以n

nn,從而求出最後每個小朋友應該擁有的糖果的個數。

我們可以用s[i

]s[i]

s[i]

來表示第i

ii個人給第i+1

i+1i+

1個人的糖果數量(如果為負,表示第i+1

i+1i+

1個人給第i

ii個人−s[

i]

-s[i]

−s[i

]顆糖果),特殊的,s[n

]s[n]

s[n]

表示第n

nn個人給第1

11個人的糖果數量。

我們可以發現,對於第i

ii個人,他的手上拿著的糖果數應為a[i

]+s[

i−1]

a[i]+s[i-1]

a[i]+s

[i−1

],即他原本擁有的糖果和第i−1

i-1i−

1個人給他的糖果,又由於每個人應拿的糖果數為sum

sumsu

m,所以a[i

]+s[

i−1]

−sum

a[i]+s[i-1]-sum

a[i]+s

[i−1

]−su

m即為他要交給第i+1

i+1i+

1個人的糖果數。

即s [i

]=a[

i]+s

[i−1

]−su

ms[i]=a[i]+s[i-1]-sum

s[i]=a

[i]+

s[i−

1]−s

um。那麼ans

=sum

i=1n

∣s[i

]−s∣

ans=sum_^n |s[i]-s|

ans=su

mi=1

n​∣s

[i]−

s∣其中,s

ss為乙個定值。而我們的目的就是取乙個合適的s

ss使ans

ansan

s最小。

如何求解

那麼,這道題目就變成了乙個我們很熟悉的乙個經典數學問題了,我們可以將s[1

]∼s[

n]

s[1]\sim s[n]

s[1]∼s

[n]一一對應到數軸上,不難發現,最優的s

ss應為s

ss陣列的中位數

這樣一來,這題就很簡單了。

**

#include

#define max(x,y) (x>y?x:y)

#define min(x,y) (x#define ll long long

#define n 1000000

using

namespace std;

int n,a[n+5]

,s[n+5]

;int

read()

void

write

(ll x)

intmain()

BZOJ 1045 糖果傳遞 數學 遞推

1045 haoi2008 糖果傳遞 time limit 10 sec memory limit 162 mb submit 2975 solved 1327 submit status discuss description 有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每...

BZOJ1045 糖果傳遞(基於貪心的數學題)

點此看題面 大致題意 有 n 個小朋友坐成一圈,每人有 a i 個糖果。每人只能給左右兩人傳遞糖果,傳遞乙個糖果代價為1,求使所有人獲得均等糖果的最小代價。這題其實是一道帶有濃厚數學色彩的貪心題。我們可以先用 sum 來統計 a i 之和,然後將 sum 除以 n 從而求出最後每個小朋友應該擁有的糖...

BZOJ 1045 HAOI2008 糖果傳遞

有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞乙個糖果代價為1。第一行乙個正整數n 987654321,表示小朋友的個數 接下來n行,每行乙個整數ai,表示第i個小朋友得到的 糖果的顆數 求使所有人獲得均等糖果的最小代價。4 1254 4 結論題 設每個人剛開始有a...