有n個小朋友坐成一圈,每人有ai個糖果。每人只能給左右兩人傳遞糖果。每人每次傳遞乙個糖果代價為1。
求使所有人獲得均等糖果的最小代價。
首先你可以去看看這道題
這道題其實就是把每次移動任意張紙牌換成每次移動一張,然後變成環形。
不是環形的話把上一道題第一種做法的ans++
換成ans+=abs(a[i]-sum)
,第二種做法中的bool()
變成abs
就好了
那麼如何處理環形呢?
我們考慮上一題中的第二種方法。
如果給每乙個位置上的糖果數減去平均數個,那麼我們最終的目標就是讓每個位置都為0
也就是字首和均為零
對於環形的話,我們可以在任意位置斷開,因為總有兩個相鄰位置是不需要傳遞的
證明不難
有可能的反例無非就是以下情況同時成立:
存在某乙個位置同時從兩側接受糖果
存在某乙個位置同時向兩側給予糖果
貪心一下,每乙個位置的糖果**都一定是距離自己最近的乙個糖果過量位置
所以乙個糖果過剩位置一定會選取距離糖果缺少位置最近的方向進行傳遞
若有奇數個位置,如下圖
6要向2傳遞蘋果,他一定不會走3這一邊
要讓6同時向兩邊傳送蘋果,只能在2,3同時不夠時
此時,2,3中間不會存在互動
若有偶數個位置
則6
−>
26->2
6−>
2可以選擇任意方向傳遞,2,3和2,9之中必有乙個是不需要傳遞的。
設從k ,k
+1k,k+1
k,k+
1中間斷開,計算傳遞數總和就是
∑ i=
1k∣s
i+sn
−sk∣
+∑i=
k+1n
∣si−
sk∣\sum\limits^_\vert s_i+s_n-s_k\vert+\sum\limits^_\vert s_i-s_k\vert
i=1∑k
∣si
+sn
−sk
∣+i=
k+1∑
n∣s
i−s
k∣s
is_i
si為i
ii位置的字首和減去平均數的iii倍
易得s n=
0s_n=0
sn=
0所以題目其實就是求mink
=1n(
∑i=1
n∣si
−sk∣
)\min\limits_^(\sum\limits_^\vert s_i-s_k\vert)
k=1minn
(i=1
∑n∣
si−
sk∣
)中位數嘛!
ac**如下了:
#include
#include
using
namespace std;
intabs
(const
int x)
void
read
(int
&x)int a[
1110000];
intmain()
P2512 HAOI2008 糖果傳遞 題解
同步 原題鏈結 簡要題意 一開始每個人有若干糖果,每個人每次將 1 11 個糖果傳遞給相鄰 認為 1 11 號與 n nn 號也相鄰 的乙個人需要 1 11 的代價。求讓所有人的糖果一樣的最小代價。顯然,如果 1 11 號與 n nn 號不相鄰,那就退化了成了 p1031 均分紙牌,但理想是美好的,...
P2512 HAOI2008 糖果傳遞 題解
csdn同步 原題鏈結 簡要題意 一開始每個人有若干糖果,每個人每次將 1 個糖果傳遞給相鄰 認為 1 號與 n 號也相鄰 的乙個人需要 1 的代價。求讓所有人的糖果一樣的最小代價。顯然,如果 1 號與 n 號不相鄰,那就退化了成了 p1031 均分紙牌,但理想是美好的,現實是殘酷的,所以我們要著手...
洛谷 P2511 HAOI2008 木棍分割
這題卡常,別用long long 這題第一問好搞,直接二分答案 第二問,凡是看到求方案數並於組合數一定沒有關係的一定用 dp 解決!然後定義狀態,顯然 轉移就是 然後我就不會優化了,看了題解,發現自己思維僵化竟然如此簡單 然後可以用字首和優化 要用滾動陣列 luogu judger enable o...