NOI2015 荷馬史詩

2022-04-30 00:42:22 字數 2564 閱讀 6371

題面:

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

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個字元組成的字串。

看資料範圍及樣例

題解:

如果學過huffman tree這題就不難了!

當然只知道huffman tree還是不行的,還要知道哈夫曼編碼,

哈夫曼樹貌似一開始就是用來獲取哈夫曼編碼的?

這個網上講解很多,就不在多講。

此題中如果按照出現次數為權值來構建哈夫曼樹,則總長度一定最小,

原版哈夫曼樹是2進製的,因此只能放2叉,

但這裡是k進製,所以就可以放k叉了,

所以每次用優先佇列找出前k小然後合併即可

但是要注意如果k != 2的話,就要保證每次合併都有k個節點(直到最後合併成乙個),

所以要在最開始補一些空節點進去,

因為每次都是拿出k個,放入乙個,所以實際上是消掉了(k-1)個,

然後最後需要剩下乙個,因此我們需要n % (k-1) == 1,

然後補齊需要的即可

那為什麼用出現次數作為權值就最優呢?

因為出現次數越大的單詞越淺,所以編碼長度也越小,自然總長度就最小了

但是這裡還需要注意乙個東西,就是第二問的要求,

需要最長的編碼最短,依舊是用貪心的思想,

在權值相同的情況下,每次優先合併被合併次數少的節點(最深的節點更淺)

1 #include2

using

namespace

std;

3#define r register int

4#define ac 100100

5#define ac 500100

6#define getchar() *o++

7#define ll long long

8char read[5000100],*o=read;

9int

n,k,id,deep;

10int d[ac];//

w為點權(包括新增點)

11int

head[ac],next[ac],date[ac],tot;

12ll ans;

13 ll w[ac];//

error!!!權值很大的啊

14bool

done;

15struct

cmp1

21};

2223 priority_queue,cmp1>q;

24/*

哈弗曼編碼,這樣是最短的,但無需獲取具體的編碼,

25只要獲得每個單詞對應的出現次數(題目給定)和編碼長度(哈弗曼樹深度)即可,

26因為是k進製,所以建立k叉哈弗曼樹,最後dfs一遍獲取每個葉節點的深度,

27然後對出現次數與深度的積求和即可

*/28

inline ll read()

2935

36 inline void add(int f,int

w)37

4041

void dfs(int x,int

dep)

4250

for(r i=head[x]; i ;i=next[i])

5155}56

57bool

build()

5871 ++d[x];//

這次合併也要算啊

72q.push(x);

73 done=true;74

return

true;75

}7677void

pre()

7886

if(k != 2)//

但是只有不為二叉的時候才要考慮這些87

93else

94if(n % (k-1) != 1) //

huffman要求完美合併?

9599

}100

}101

102void

work()

103109

110int

main()

111

荷馬史詩 NOI2015 解析

比較簡單,這道題需要貪心解決。不需要任何複雜的資料結構,乙個luo的堆就足夠了。本題的意思就是 給定n種單詞及在文字中各自出現的頻率,要求利用二進位制串對其進行字首編碼,使得壓縮後的文字長度最短。改用k進製串?最長的單個單詞編碼最短?我們知道有個叫huffman編碼的東西就是來解決這類編碼問題的。所...

荷馬史詩(NOI2015)提高組

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

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

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