P2512 HAOI2008 糖果傳遞 題解

2021-10-04 20:17:03 字數 2196 閱讀 2046

同步

原題鏈結

簡要題意:

一開始每個人有若干糖果,每個人每次將 1

11 個糖果傳遞給相鄰(認為 1

11 號與 n

nn 號也相鄰)的乙個人需要 1

11 的代價。求讓所有人的糖果一樣的最小代價。

顯然,如果 1

11 號與 n

nn 號不相鄰,那就退化了成了 p1031 均分紙牌,但理想是美好的,現實是殘酷的,所以我們要著手環的問題。

破環為鏈。

考慮在**把環切斷,然後暴力跑均分紙牌的貪心。

時間複雜度:o(n

2)

o(n^2)

o(n2).

實際得分:0pt

0pt0p

t ~ 100pt

s100pts

100pts

.(出題人沒寫部分分)

首先我們算出 ∑i=

1nai

n\frac^n a_i}

n∑i=1n

​ai​

​ 即平均數。

然後,用 x

ix_i

xi​ 表示 i

ii 號給了 i−1

i-1i−

1 號若干糖果,而 x

1x_1

x1​ 就是 1

11 號給了 n

nn 號若干糖果。如果 x

i<

0x_i < 0

xi​<

0 則說明是 i−1

i-1i−

1 號(i=1

i=1i=

1 時為 n

nn 號) 給了 i

ii 號若干糖果。並用 c

ic_i

ci​ 表示 i

ii 號節點比平均糖果多的值,少則為負數,然後 c

ic_i

ci​ 對自己做字首和。

這時,我們想要最小化 x

ix_i

xi​ 的絕對值之和,也即:

∣ x∣

+∑i=

1n−1

∣x−c

i∣

|x| + \sum_^ |x - c_i|

∣x∣+i=

1∑n−

1​∣x

−ci​

∣為什麼呢?你可以這樣理解,每一組給糖果的關係就是字首和的差,然後你搞出乙個點叫做 x

xx 實現這個過程。

然後你看一眼這個式子,你發現 x1−

ci

x_1 - c_i

x1​−ci

​ 是數軸上表示 x

1x_1

x1​ 的點到表示 c

ic_i

ci​ 的點的距離(來自小學數學老師),然後問題就退化為:

找乙個 x

xx 使得它與 每乙個 c

ic_i

ci​ 的距離之和最小。

這小學貪心題啊,取中位數就行了。

時間複雜度:o(n

log⁡n)

o(n \log n)

o(nlogn)

.(主要是取中位數要排序,如果用資料結構可能會優化到線性)

實際得分:100pt

s100pts

100pts

.

#pragma gcc optimize(2)

#include

using

namespace std;

typedef

long

long ll;

const

int n=

1e6+1;

inline ll read()

ll x=0;

while

(ch>=

'0'&& ch<=

'9') x=

(x<<3)

+(x<<1)

+ch-

'0',ch=

getchar()

;return x*f;

}ll a[n]

,x[n]

,ans=0;

ll n,sum=0;

//sum 是平均數

intmain()

P2512 HAOI2008 糖果傳遞 題解

csdn同步 原題鏈結 簡要題意 一開始每個人有若干糖果,每個人每次將 1 個糖果傳遞給相鄰 認為 1 號與 n 號也相鄰 的乙個人需要 1 的代價。求讓所有人的糖果一樣的最小代價。顯然,如果 1 號與 n 號不相鄰,那就退化了成了 p1031 均分紙牌,但理想是美好的,現實是殘酷的,所以我們要著手...

洛谷P2512 HAOI2008 糖果傳遞 題解

有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞乙個糖果代價為1。求使所有人獲得均等糖果的最小代價。首先你可以去看看這道題 這道題其實就是把每次移動任意張紙牌換成每次移動一張,然後變成環形。不是環形的話把上一道題第一種做法的ans 換成ans abs a i sum ...

HAOI2008 糖果傳遞

洛谷題面 和題解差不多,加了點證明。有 n 個小朋友坐成一圈,每人有 a i 個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞乙個糖果代價為 1 設 e 表示所有小朋友糖果數量的平均數,因為所有小朋友糖果總數不會變,所以最後每個人的糖果數都會變成平均數。設 num i 表示第 i 個小朋友往左傳的糖...