荷马史诗 NOI2015 解析
比较简单,这道题需要贪心解决。
不需要任何复杂的数据结构,一个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=;
type rec=record
num,deep:int64;
end;
var n,k,i,j,tot:longint;ans,mxdep:int64;
node,now:rec;
a:array[..maxn]of int64;
q:array[..maxn]of rec;
procedure swap(var a,b:rec);
var t:rec;
begin
t:=a; a:=b; b:=t;
end;
procedure up(x:longint);
begin
while x> do begin
if (q[x].num>q[x div ].num)or((q[x].num=q[x div ].num)and(q[x].deep>q[x div ].deep))//注意多判断深度
then break;
swap(q[x],q[x div ]);
x:=x div ;
end;
end;
procedure down(x:longint);
var lson,rson,son,pd:longint;
begin
while x<tot do begin
lson:=*x; //pd=;
rson:=*x+; //pd=;
pd:=;
if lson>tot then break;
if (lson<tot)and((q[lson].num>q[rson].num)or(q[lson].num=q[rson].num)and(q[lson].deep>q[rson].deep)) then pd:=;
if pd= then son:=lson
else son:=rson;
if (q[x].num<q[son].num)or((q[x].num=q[son].num)and(q[x].deep<q[son].deep)) then break;
swap(q[x],q[son]);
x:=son;
end;
end;
begin
readln(n,k);
for i:= to n do read(a[i]);
if k<> then
while n mod (k-)<> do begin
inc(n); a[n]:=;
end;//如果不是2叉堆需要初始化保证huffman树最后一层的元素到达k个,方便操作
tot:=;
for i:= to n do begin
inc(tot);
q[tot].num:=a[i];
q[tot].deep:=;
up(tot);
end;//建堆
while tot<> do begin
node.num:=;node.deep:=; mxdep:=;//k个元素的和、深度、最大深度
for i:= to k do begin
now:=q[];
swap(q[],q[tot]);
dec(tot);
down();
node.num:=node.num+now.num;
mxdep:=max(mxdep,now.deep);
end;//由于是k进制所以需要取出堆中k个元素
ans:=ans+node.num;//累加
node.deep:=mxdep+;//深度++
inc(tot);
q[tot]:=node;
up(tot);//放回去
end;
writeln(ans);
writeln(mxdep+);//打印
end.
荷马史诗 NOI2015 解析的更多相关文章
- 洛谷P2168 荷马史诗 [NOI2015]
题目描述 追逐影子的人,自己就是影子 ——荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛&g ...
- [BZOJ4198][Noi2015]荷马史诗
4198: [Noi2015]荷马史诗 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 700 Solved: 365[Submit][Status] ...
- BZOJ_4198_[Noi2015]荷马史诗_huffman实现
BZOJ_4198_[Noi2015]荷马史诗_huffman实现 题意: Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗> ...
- 【NOI2015】荷马史诗[Huffman树+贪心]
#130. [NOI2015]荷马史诗 统计 描述 提交 自定义测试 追逐影子的人,自己就是影子. ——荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读 ...
- 【BZOJ4198】【NOI2015】荷马史诗(贪心,Huffman树)
[BZOJ4198][NOI2015]荷马史诗(贪心,Huffman树) 题面 BZOJ 洛谷 题解 合并果子都是不知道多久以前做过的了.现在才知道原来本质就是一棵哈夫曼树啊. 这题我们仔细研究一下题 ...
- 【bzoj4198】【Noi2015】荷马史诗
4198: [Noi2015]荷马史诗 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2200 Solved: 1169[Submit][Statu ...
- 洛谷 P2168 [NOI2015]荷马史诗 解题报告
P2168 [NOI2015]荷马史诗 题目描述 追逐影子的人,自己就是影子 --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷 ...
- UOJ#130 【NOI2015】荷马史诗 K叉哈夫曼树
[NOI2015]荷马史诗 链接:http://uoj.ac/problem/130 因为不能有前缀关系,所以单词均为叶子节点,就是K叉哈夫曼树.第一问直接求解,第二问即第二关键字为树的高度. #in ...
- 【BZOJ4198】[Noi2015]荷马史诗 贪心+堆
[BZOJ4198][Noi2015]荷马史诗 Description 追逐影子的人,自己就是影子. ——荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅 ...
随机推荐
- Codeforces round 1111
CF Div 2 537 比赛链接 感觉题目难度OK,五个题都能做,后俩题考察人的翻译水平... 另外,$Claris$太强了... A 直接按照题意模拟,不知道为啥有人会被× 代码: #includ ...
- EZ 2018 03 23 NOIP2018 模拟赛(五)
链接:http://211.140.156.254:2333/contest/65 这次Rating重回Rank18,我是20的守门员(滑稽) 这次题目和数据普遍偏水,我T2打错了一个变量名竟然过了所 ...
- 【php增删改查实例】第六节 - 部门管理模块(开始)
sql建表语句详见:https://www.jianshu.com/p/c88077ed9073 1.新建html模板 新建一个空白的txt文档,然后把后缀名改为.html 用任意一个编辑器打开,比如 ...
- python 23 种 设计模式
频率 所属类型 模式名称 模式 简单定义 5 创建型 Singleton 单件 保证一个类只有一个实例,并提供一个访问它的全局访问点. 4 创建型 Abstract Factory 抽象工厂 提供一个 ...
- Express模版引擎hbs备忘
最近几天折腾了下express,想找个合适的模版引擎,下面是一些折腾过程的备忘 选择标准 选择一门模版语言时,可能会考虑的几点 语法友好(micro tmpl那种语法真是够了) 支持模版嵌套(子模版的 ...
- HTML 脚本 (Script) 实例
1.JavaScript 使 HTML 页面具有更强的动态和交互性.HTML script 元素<script> 标签用于定义客户端脚本,比如 JavaScript. script 元素既 ...
- Svn 提示错误:previous operation has not finished 解决方案
svn提交遇到恶心的问题,可能是因为上次cleanup中断后,进入死循环了. 解决方案: 找到你项目的.svn文件,查看是否存在wc.db 网上下载SQLite Expert工具,手动打开wc.db, ...
- cbuild-一个创建和管理C++项目的工具
cbuild-一个创建和管理C++项目的工具 介绍: 这是个人开发的一个管理C++项目的工具,用shell脚本编写. 可能会不定期更新,也欢迎大家一起完善. 当前开发版本0.5.各版本功能如下: ve ...
- Ubuntu Google Chrome
Chrome安装 添加下载源 sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.l ...
- EOS开发基础之三:使用cleos命令行客户端操作EOS——关于钱包wallet和账户account
好了,上一节我们已经讲了关于wallet的一些基础操作,基本了解了怎么去创建一个钱包,怎么去查看钱包.上锁和解锁钱包等,这一节咱们就来开始操作账户account吧. 上一节讲到了每一个account都 ...