acwing 貪心(哈夫曼樹)

2021-10-06 06:41:54 字數 898 閱讀 5120

題目:合併果子

演算法思路:每次選擇最小的兩個點合併即可,利用優先佇列(小根堆)

這些點會構成一棵哈夫曼樹(完全二叉樹)。

.處於深度最深的點會被合併最多次(可以理解為優先合併)。

先證明以下兩點:

①權值最小的兩個點,深度一定最深,並且可以互為兄弟(即優先合併,並且區域性代價最小)

證明:假設最小的兩點深度不是最深,設點a、f是最小的兩個點。

當交換點b和點f後,因為最終的結果等於每個點的大小✖每個點到樹根的距離,其餘點不變,

因此最終的結果會從3b+2f變成3f+2b,因為f②一定可以通過區域性最優解得到全域性最優解

證明:設函式f(x)表示一棵大小為x的哈夫曼樹的代價。f(x)表示數大小為x的最小代價

由區域性最優解得:f(n) = f(n-1) + a + b

因為不管是哪一種方案,第一步總是要合併a+b,因此先不考慮a+b,只考慮f(n-1)

於是問題變為求f(n-1)的最優解,於是可以再呼叫區域性最優解的方案,以此類推直到n=1。

於是證得:可以通過區域性最優解的方式得到全域性最優解

#include

#include

#include

using

namespace std;

intmain()

int res =0;

while

(heap.

size()

>1)

cout << res << endl;

return0;

}

貪心 哈夫曼編碼 哈夫曼樹

解決問題 哈夫曼樹 眾所周知,計算機以01串來儲存和運算。所以,如果我們想要存乙個字元或漢字,例如a,計算機會將它變為乙個01串,這個串就是a的編碼。如果我們輸入了乙個詞 cat。如果a的編碼是1,c的編碼是10,t的編碼是11,那麼 cat 對應的編碼就是 10111 好了,那麼問題來了 1011...

哈夫曼編碼 哈夫曼樹

1.定義 哈夫曼編碼主要用於資料壓縮。哈夫曼編碼是一種可變長編碼。該編碼將出現頻率高的字元,使用短編碼 將出現頻率低的字元,使用長編碼。變長編碼的主要問題是,必須實現非字首編碼,即在乙個字符集中,任何乙個字元的編碼都不是另乙個字元編碼的字首。如 0 10就是非字首編碼,而0 01不是非字首編碼。2....

哈夫曼樹 哈夫曼編碼

定義從a結點到b結點所經過的分支序列為從a結點到b結點的路徑 定義從a結點到b結點所進過的分支個數為從a結點到b結點的路徑長度 從二叉樹的根結點到二叉樹中所有結點的路徑長度紙盒為該二叉樹的路徑長度 huffman樹 帶權值路徑長度最小的擴充二叉樹應是權值大的外界點舉例根結點最近的擴充二叉樹,該樹即為...