P2512 HAOI2008 糖果傳遞 題解

2022-02-14 18:25:14 字數 1380 閱讀 5413

csdn同步

原題鏈結

簡要題意:

一開始每個人有若干糖果,每個人每次將 \(1\) 個糖果傳遞給相鄰(認為 \(1\) 號與 \(n\) 號也相鄰)的乙個人需要 \(1\) 的代價。求讓所有人的糖果一樣的最小代價。

顯然,如果 \(1\) 號與 \(n\) 號不相鄰,那就退化了成了 p1031 均分紙牌,但理想是美好的,現實是殘酷的,所以我們要著手環的問題。

破環為鏈。

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

時間複雜度:\(o(n^2)\).

實際得分:\(0pt\) ~ \(100pts\).(出題人沒寫部分分)

首先我們算出 \(\frac^n a_i}\) 即平均數。

然後,用 \(x_i\) 表示 \(i\) 號給了 \(i-1\) 號若干糖果,而 \(x_1\) 就是 \(1\) 號給了 \(n\) 號若干糖果。如果 \(x_i < 0\) 則說明是 \(i-1\) 號(\(i=1\) 時為 \(n\) 號) 給了 \(i\) 號若干糖果。並用 \(c_i\) 表示 \(i\) 號節點比平均糖果多的值,少則為負數,然後 \(c_i\) 對自己做字首和。

這時,我們想要最小化 \(x_i\) 的絕對值之和,也即:

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

\]為什麼呢?你可以這樣理解,每一組給糖果的關係就是字首和的差,然後你搞出乙個點叫做 \(x\) 實現這個過程。

然後你看一眼這個式子,你發現 \(x_1 - c_i\) 是數軸上表示 \(x_1\) 的點到表示 \(c_i\) 的點的距離(來自小學數學老師),然後問題就退化為:

找乙個 \(x\) 使得它與 每乙個 \(c_i\) 的距離之和最小。

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

時間複雜度:\(o(n \log n)\).(主要是取中位數要排序,如果用資料結構可能會優化到線性)

實際得分:\(100pts\).

#pragma gcc optimize(2)

#includeusing 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 是平均數

int main()

P2512 HAOI2008 糖果傳遞 題解

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

洛谷P2512 HAOI2008 糖果傳遞 題解

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

HAOI2008 糖果傳遞

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