比較簡單,這道題需要貪心解決。
不需要任何複雜的資料結構,乙個luo的堆就足夠了。
本題的意思就是:給定n種單詞及在文字中各自出現的頻率,要求利用二進位制串對其進行字首編碼,使得壓縮後的文字長度最短。
改用k進製串?最長的單個單詞編碼最短?
我們知道有個叫huffman編碼的東西就是來解決這類編碼問題的。所以嘗試用huffman思想去解題。
如果編碼的進製是2進製就好了,但是題目的資料只有少部分是2進製編碼的,
所以我們要仿造二叉形式huffman一次彈出兩個(最小值)成k叉一次彈出k個(最小值);
二叉堆來實現(不是用k叉堆,這樣做時間複雜度太高且不易實現)
每一次彈出最值時就是連續取二叉堆的前k個數就可以了。
堆中儲存huffman樹中串出現頻率和,以及huffman樹的深度;
比較時先比較頻率和,再比較深度(不可不比,要保證huffman樹高最小);
每次合併時,ans都要加上合併後長度(要不然求的是串頻率和),而深度在取最大後再插入時要加1;
當堆中只有乙個元素時退出,這時,ans和該元素深度即為答案;
注意到初始化堆的時候最後一層到不了k個怎麼辦?
初始化時注意各元素深度為0,若n!≡1mod(k-1),那麼補齊n,增加的新元素頻率為0(顯然),深度為0;
堆的建立就不詳細說了。
uses math;const maxn=100010
;type rec=record
num,deep:int64;
end;
varn,k,i,j,tot:longint;ans,mxdep:int64;
node,now:rec;
a:array[1..maxn]of
int64;
q:array[1..maxn]of
rec;
procedure swap(var
a,b:rec);
vart:rec;
begin
t:=a; a:=b; b:=t;
end;
procedure
up(x:longint);
begin
while x>1
dobegin
if (q[x].num>q[x div
2].num)or((q[x].num=q[x div
2].num)and(q[x].deep>q[x div
2].deep))//注意多判斷深度
then
break;
swap(q[x],q[x
div2
]); x:=x div2;
end;end
;procedure
down(x:longint);
varlson,rson,son,pd:longint;
begin
while xdo
begin
lson:=2*x; //pd=1
; rson:=2*x+1; //pd=2
; pd:=1;
if lson>tot then
break;
if (lsonand((q[lson].num>q[rson].num)or(q[lson].num=q[rson].num)and(q[lson].deep>q[rson].deep)) then pd:=2;
if pd=1
then son:=lson
else son:=rson;
if (q[x].numor((q[x].num=q[son].num)and(q[x].deepthen
break;
swap(q[x],q[son]);
x:=son;
end;end
;begin
readln(n,k);
for i:=1
to n do
read(a[i]);
if k<>2
then
while n mod (k-1)<>1
dobegin
inc(n); a[n]:=0;
end;//如果不是2叉堆需要初始化保證huffman樹最後一層的元素到達k個,方便操作
tot:=0;
for i:=1
to n do
begin
inc(tot);
q[tot].num:=a[i];
q[tot].deep:=0
; up(tot);
end;//建堆
while tot<>1
dobegin
node.num:=0;node.deep:=0; mxdep:=0
;//k個元素的和、深度、最大深度
for i:=1
to k do
begin
now:=q[1
]; swap(q[
1],q[tot]);
dec(tot);
down(1);
node.num:=node.num+now.num;
mxdep:=max(mxdep,now.deep);
end;//由於是k進製所以需要取出堆中k個元素
ans:=ans+node.num;//累加
node.deep:=mxdep+1
;//深度++
inc(tot);
q[tot]:=node;
up(tot);//放回去
end; writeln(ans);
writeln(mxdep+1
);//列印
end.
NOI2015 荷馬史詩
題面 追逐影子的人,自己就是影子 荷馬 allison 最近迷上了文學。她喜歡在乙個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的 荷馬史詩 但是由 奧德賽 和 伊利亞特 組成的鴻篇巨制 荷馬史詩 實在是太長了,allison 想通過一種編碼方式使得它變得短一些。一部 荷馬史詩 中有n種...
荷馬史詩(NOI2015)提高組
追逐影子的人,自己就是影子 荷馬 allison 最近迷上了文學。她喜歡在乙個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的 荷馬史詩 但是由 奧德賽 和 伊利亞特 組成的鴻篇巨制 荷馬史詩 實在是太長了,allison 想通過一種編碼方式使得它變得短一些。一部 荷馬史詩 中有n種不同的...
NOI 2015 荷馬史詩 (哈夫曼樹)
問題描述 追逐影子的人,自己就是影子。荷馬 allison 最近迷上了文學。她喜歡在乙個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的 荷馬史詩 但是由 奧德賽 和 伊利亞特 組成的鴻篇巨制 荷馬史詩 實在是太長了,allison 想通過一種編碼方式使得它變得短一些。一部 荷馬史詩 中有...