NOI 2015 荷馬史詩 (哈夫曼樹)

2021-08-09 22:43:35 字數 2366 閱讀 5152

問題描述

追逐影子的人,自己就是影子。 ——荷馬

allison 最近迷上了文學。她喜歡在乙個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的《荷馬史詩》。但是由《奧德賽》和《伊利亞特》組成的鴻篇巨制《荷馬史詩》實在是太長了,allison 想通過一種編碼方式使得它變得短一些。

一部《荷馬史詩》中有 n 種不同的單詞,從 1 到 n 進行編號。其中第 i 種單詞出現的總次數為 wi。allison 想要用 k 進製串 si 來替換第 i 種單詞,使得其滿足如下要求:

對於任意的 1≤i,j≤n,i≠j,都有:si 不是 sj 的字首。

現在 allison 想要知道,如何選擇 si,才能使替換以後得到的新的《荷馬史詩》長度最小。在確保總長度最小的情況下,allison 還想知道最長的 si 的最短長度是多少?

乙個字串被稱為 k 進製字串,當且僅當它的每個字元是 0 到 k−1 之間(包括 0 和 k−1)的整數。

字串 str1 被稱為字串 str2 的字首,當且僅當:存在 1≤t≤m,使得 str1=str2[1..t]。其中,m 是字串 str2 的長度,str2[1..t] 表示 str2 的前 t 個字元組成的字串。

輸入格式

輸入檔案的第 1 行包含 2 個正整數 n,k,中間用單個空格隔開,表示共有 n 種單詞,需要使用 k 進製字串進行替換。

接下來 n 行,第 i+1 行包含 1 個非負整數 wi,表示第 i 種單詞的出現次數。

輸出格式

輸出檔案包括 2 行。

第 1 行輸出 1 個整數,為《荷馬史詩》經過重新編碼以後的最短長度。

第 2 行輸出 1 個整數,為保證最短總長度的情況下,最長字串 si 的最短長度。

樣例輸入1:

4 2

1 1 2 2

樣例輸入2:

6 3

1 1

3 3 9 9

樣例輸出1:

12

2

樣例輸出2:

36

3

此題的解是多叉哈夫曼樹,哈夫曼樹是用於解決最短編碼的一種編碼方法。

首先,將每種字元視為點,出現次數視為點權,那麼每次選取權最小的k個點合成乙個新點,新點點權等於各點點權和,如此最後只剩乙個點時,就構好了k叉哈夫曼樹,至於具體的編碼,舉個例子說明即可。

如上圖的二叉哈夫曼樹,那麼a的編碼為00,b的編碼為01,c的編碼為1

至於最長編碼的最短長度,實際上就是要求哈夫曼樹的深度盡量小,那麼只需要每次選權值最小且深度深度盡量小的子樹合併即可。

具體實現時,可以將點分成已合併的點和未合併的點,維護兩個佇列的單調性,每次取隊首即可。

**:

#include

#include

#include

#define n 10000005

#define int long long

using namespace std

;struct nodea[n],b[n];

bool operator

int n,k,l1=1,r1,l2=1,r2

;main()

if((n-1)%(k-1))r1+=k-1-(n-1)%(k-1);

sort(a+l1,a+r1+1);

while(r1-l1+r2-l2+2>1)

else if(l2>r2)

else if(a[l1].v+=a[l1].v

; tmp.sum+=a[l1].sum+a[l1].x

; tmp.x+=a[l1].x

; tmp.dep=max(tmp.dep,a[l1].dep+1);

l1++;

}else

i++;

}b[++r2]=tmp;

}printf("%lld\n%lld",b[l2].sum,b[l2].dep);

}

NOI2015 荷馬史詩

題面 追逐影子的人,自己就是影子 荷馬 allison 最近迷上了文學。她喜歡在乙個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的 荷馬史詩 但是由 奧德賽 和 伊利亞特 組成的鴻篇巨制 荷馬史詩 實在是太長了,allison 想通過一種編碼方式使得它變得短一些。一部 荷馬史詩 中有n種...

NOI 2015 荷馬史詩 k叉哈夫曼樹 堆優化

題目大意 給出n個數字w,代表n個字母出現的次數,給出k。要求用k進製的數字串si替換第i個字母,且替換之後要求替換後的文章無二義性 這裡的無二義性是指對於任意的 1 i,j n i j,都有 si不是sj的字首 求替換後最短的文章的長度 長度len sigma w i strlen si 和這種情...

NOI 2015 荷馬史詩 k叉哈夫曼樹 堆優化

原址 題目大意 給出n個數字w,代表n個字母出現的次數,給出k。要求用k進製的數字串si替換第i個字母,且替換之後要求替換後的文章無二義性 這裡的無二義性是指對於任意的 1 i,j n i j,都有 si不是sj的字首 求替換後最短的文章的長度 長度len sigma w i strlen si 和...