哈弗曼樹 WOJ2343 圍欄維修

2021-08-30 04:43:52 字數 1112 閱讀 2415

【描述】

農民 john 希望修復圍繞農場的一小段圍欄。他測量了一下,發現需要n (1 <= n <= 20,000) 根木頭,每根都有某乙個整數長度 li (1 <= li <= 50,000) 單位長度。 他買了一根很長的很長的木頭,正好能夠鋸出他所需要的n根木頭。(即它的長度正好等於 li的總和) fj 忽略鋸口,鋸掉的木屑產生的長度損失忽略不計,你也可以忽略它。

fj 遺憾的發現他自己沒有用於切木頭的鋸子,所以他就帶著那根很長的木頭來到了農民 don 的農場,想問他借乙個鋸子。

農民 don是乙個保守的資本家,他不願意借鋸子給 fj ,但願意自己來切這n-1刀,每一次 都向fj收取費用。每次的收費正好等於你要鋸的那根木頭的總長度。例如,你要鋸一根長度 為21的木頭,就花費21分錢。

農民 don 然後讓農民 john 自己決定每次鋸木頭的順序和位置。幫助農民 john 確定鋸出 這n根木頭的最小總花費。 fj 知道可以有很多種不同的切割方式,不同的方式可能得到 不同的總花費,這是因為木頭在鋸的過程中的長度不一。

【輸入】

【輸出】

【樣例輸入】[複製] 3

858【樣例輸出】[複製]

【提示】

輸出解釋:

原本的木頭長度為 8+5+8=21。第一次鋸的花費是 21,應該切成兩段長度分別是13和8。 第二次花費是13,把長度是13的木頭鋸成8和5。總花費是21+13=34。但如果先將21鋸成 16和5,第二次將花費16,導致總花費達到37 (大於34)。

【思路】倒著貪心。我們最後得到了n個木頭。每次當前取出最小的兩個合併之後再丟回去。最後合併成乙個木頭。一定是最優解。正確性大概就是哈弗曼樹的最優性證明。具體實現用乙個堆維護就行了。注意統計費用開longlong。

本題可以轉化為乙個哈弗曼樹的構造。具體大概就是乙個有n個葉子結點的二叉樹。每個葉子結點有乙個權值,每個葉子結點的貢獻就是【葉子結點到根節點的距離】乘上【點權】。現在要讓這個總費用最小。如上所述。。。。

#includeusing namespace std;

int read()

int n;long long ans=0;

priority_queueq;

int main()

cout<}

哈弗曼編碼 哈弗曼樹

哈弗曼編碼是依賴於字元使用頻率來建立的一種編碼,通過把使用頻率低的字元分配相對較多的01編碼,而使用頻率高的分配相對較低的01編碼,來建立最小的帶權路徑長度的樹,來最大化的獲得編碼儲存空間的一種編碼規則。這個樹稱為哈弗曼樹,也稱為最優二叉樹。這樣可以確定每乙個字元的編碼不可能成為其他字元編碼的坐子串...

哈弗曼樹與哈弗曼編碼(實現)

歷史背景 1951年,霍夫曼在mit攻讀博士學位,他和修讀資訊理論課程的同學得選擇是完成學期報告還是期末考試。導師robert fano出的學期報告題目是 查詢最有效的二進位制編碼。由於無法證明哪個已有編碼是最有效的,霍夫曼放棄對已有編碼的研究,轉向新的探索,最終發現了基於有序頻率二叉樹編碼的想法,...

資料結構之哈弗曼樹與哈弗曼編碼

一.哈弗曼樹和哈弗曼編碼先知 哈弗曼樹是二叉樹中一種特殊的樹,也被稱為最優二叉樹。其通過某種規則 權值 來構造出一哈夫曼二叉樹,在這個二叉樹中,只有葉子節點才是有效的資料節點,其他的非葉子節點是為了構造出哈夫曼而引入的!哈夫曼編碼是通過哈夫曼樹進行的一種編碼,一般情況下,以字元 0 與 1 表示。編...