荷马史诗 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 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅 ...
随机推荐
- [Baltic 2011]Lamp BZOJ2346
分析: 建图最短路,比较裸. 我们可以考虑,如果是‘\’那么,左上连右下边权为0,左下连右上边权为1,反之亦然. 卡裸spfa,加点优化能过,我就直接改成的堆优化Dijkstra 附上代码: #inc ...
- 记录一次 @Autowired 无法注入( spring依赖正常 idea显示有spring已注入的图标)导致空指针异常的原因
首先,参考 https://blog.csdn.net/weixin_40475523/article/details/81085990 然后发现 是因为我把自己的这个类加上了 @Service 注解 ...
- Django实现websocket完成实时通讯、聊天室、在线客服等
一 什么是Websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在WebS ...
- REST-framework快速构建API--频率
前面已经了解了API的认证和授权.认证,是对资源访问者的第一道门,必须有钥匙,你才能进来拿我的资源:授权,是对资源访问者的第二道门,虽然你进来了,但是你可以拿走什么资源,还是我说了算,就是授权. 当然 ...
- 配置LNPM
在 Ubuntu 系统中,可以使用 apt-get 命令来搭建 LNMP环境.这种方式较编译方式安装更加简便,因此选择使用该方式来搭建环境以供学习. 安装Nginx 使用 sudo apt-get i ...
- Gulp:插件编写入门
之前挖了个坑,准备写篇gulp插件编写入门的科普文,之后迟迟没有动笔,因为不知道该肿么讲清楚Stream这货,毕竟,gulp插件的实现不像grunt插件的实现那么直观. 好吧,于是决定单刀直入了.文中 ...
- python+selenium安装方法
一.准备工具: 下载 python[python 开发环境] http://python.org/getit/ 下载 setuptools [python 的基础包工具] http://pypi.py ...
- muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制
目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...
- kali linux 安装Nessus
Nessus 介绍: Nessus 是目前全世界最多人使用的系统漏洞扫描与分析软件.总共有超过75,000个机构使用Nessus 作为扫描该机构电脑系统的软件. 下载Nessus,我的是64为,我选择 ...
- PAT甲题题解-1055. The World's Richest (25)-终于遇见一个排序的不水题
题目简单,但解题的思路需要转换一下,按常规思路肯定超时,推荐~ 题意:给出n个人的姓名.年龄和拥有的钱,然后进行k次查询,输出年龄在[amin,amx]内的前m个最富有的人的信息.如果财富值相同就就先 ...