alias method/別名算法

alias method/別名算法

前言

一個在oi/acm比較少見的算法吧。。算法

從問題開始QAQ

有\(N(N>1)\)個物品,有屬性\(d_i\),如今要平均放進\(N-1\)個盒子裏,每一個盒子最多存在兩個物品,物品能夠分割。數組

當N=2時。

顯然兩個全放進一個盒子裏就好了。數據結構

當N>2時。

顯然咱們能夠先算出每一個盒子須要放多少,設其爲\(K\),因而\(\sum{d_i}=(N-1)K\)。
一共\(N\)個物品要放進\(N-1\)個盒子中,設其中\(d_i\)的最大值爲\(mx\),最小值爲\(mn\)。
性質1:\(mn<K\)
性質2:\(mn+mx>K\)
這兩個性質比較顯然,均可以用反證法證實的。
因而咱們能夠直接讓\(mn\)和部分\(mx\)來湊成K,多餘部分放回去,因而物品和盒子可數均減小1,遞歸便可。ide

怎麼實現

咱們須要維護增長元素,刪除元素,詢問最大最小值的一個數據結構,顯然能夠用個multiset,因而就能輕鬆作到O(nlogn)。優化

進一步優化

若是要維護最大最小值的話,就很難不帶log。(悲)。然而實際上咱們也並不是必須取最值。
咱們考慮把物品分紅兩類,一類是\(d_i<K\),其他是另外一類。
因而咱們能夠每次在兩個類中各取一個湊一個K,而後放回剩餘。
然而這麼作會有個問題,到後面可能存在全部\(d_i\)全都小於\(K\)的狀況。
其實這個狀況下能夠證實任意兩個物品都能知足加起來不小於K(就不證了吧QAQ),因而按順序合併就好。
因而如今的作法就能夠作到空間O(n),時間O(n)了。遞歸

應用

一個隨機事件包含\(n\)種狀況,每種狀況發生的機率分別爲:\(p_i\),問怎麼用產生符合這個機率的採樣方法。
這種問題的解決方法不少,好比按照機率構造數組而後在上面隨機。。
然而許多方法時間空間複雜度不夠優秀,或者在大量數據採樣時不能較好的符合發生機率。
應用別名算法,至關因而把這些總和爲1的物品分到n-1的盒子裏,每次採樣先隨機到一個盒子,再按照盒子內的比例隨機一次。
就能作到O(n)的空間和時間預處理,每次O(1)的採樣,而且採樣結果比較符合事件機率。事件

相關文章
相關標籤/搜索