有一篇文章,文章包含 n
種單詞,單詞的編號從 1 至 n,第 i 種單詞的出現次數為 wi
現在,我們要用乙個 2 進製串(即只包含 0 或 1 的串) si
來替換第 i 種單詞,使其滿足如下要求:對於任意的 1≤i,j≤n,i≠j,都有 si 不是 sj
的字首。(這個要求是為了避免二義性)
你的任務是對每個單詞選擇合適的 si
,使得替換後的文章總長度(定義為所有單詞出現次數與替換它的二進位制串的長度乘積的總和)最小。求這個最小長度。
字串 s1
(不妨假設長度為 n)被稱為字串 s2 的字首,當且僅當:s2 的長度不小於 n,且 s1 與 s2 前 n
個字元組組成的字串完全相同。
第一行乙個整數 n
,表示單詞種數。
第 2 行到第 n+1
行,第 i+1 行包含乙個正整數 wi,表示第 i
種單詞的出現次數。
輸出一行乙個整數,表示整篇文章重編碼後的最短長度。
411
22
12
一種最優方案是令 s1
=000,s2=001,s3=01,s4
=1。這樣文章總長即為 1*3+1*3+2*2+1*2=12。
另一種最優方案是令 s1
=00,s2=01,s3=10,s4
=11。這樣文章總長也為 12。
對於第 1 個測試點,保證 n=3
對於第 2 個測試點,保證 n=5
對於第 3 個測試點,保證 n=16
,且所有 wi
都相等。
對於第 4 個測試點,保證 n=1000
對於第 5 個測試點,保證所有 wi
都相等。
對於所有的 7 個測試點,保證 2≤n≤106
,wi≤1011
時間限制:2 sec
空間限制:256 mb
[我們希望越長的串出現次數越少,那麼貪心地考慮,讓出現次數少的串更長。]
[於是我們先區分出出現次數最少的 2 個串,在它們的開頭分別新增 0 和 1。]
[接著,由於它們已經被區分(想一想,為什麼?),所以我們可以把它們看作是**乙個**單詞,且其出現次數為它們的和,然後繼續上面的「添數」和「合併」操作。]
[這樣,我們不停地「合併單詞」,直到只剩 1 個單詞,即可結束。]
[可以證明這是最優的。]
[樸素的實現是 o(n2)
的,可以用二叉堆或__std::priority_queue__將其優化至 o(nlogn)
另外,為了幫助大家完成題目,我們提供了只包含了輸入輸出功能的程式模板,也提供了含有演算法的大部分實現細節的程式。
你可以根據自己的實際情況,在這些程式的基礎上進行作答,或不參考這些程式,這將與你的得分無關。
改編自:【noi2015】荷馬史詩(
python第一周心得 Python第一周總結
變數 不能為系統自帶的內建函式,如def,help,sum等等 變數不能已下劃線數字來開頭,對大小寫敏感 變數後直接接數字,則被賦值為整型,如何加引號則賦值型別為字串str型別 a 1 整型 int b 2 字串 str 用print 直接輸出 a hello print a 在 使用者想要同時輸出...
第一周周記
下面是整個文章的第二部分,日常的安利 這周的話,除了整體恢復正常,週末我也購置了我的第一塊外接鍵盤,這裡的話我選擇的是國產的靜電容鍵盤niz的plum 87鍵鍵盤。今天拿到這個鍵盤第一天,整體使用了一下,尺寸配合著15寸的蘋果macbook pro可以說恰到好處,除此以外,整個鍵盤還是給我不少驚喜的...
寒假第一周
寫了這個標題,感覺有點像寫周記的味道.那就盡量堅持這個寒假裡至少每週一篇吧。這幾天學校裡真的好清靜了,實驗室和寢室都沒人了。其實說起來這周算是我們寒假的第二週了吧,14號就全部考完了,從放假的基本定義來看,那時候就算是寒假了。只不過上週這邊人還比較多,而且本科生也都沒考完,校歷上也是這週才算開始放假...