題面:
追逐影子的人,自己就是影子 ——荷馬
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 #include2using
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 想通過一種編碼方式使得它變得短一些。一部 荷馬史詩 中有...