当前位置: 首页 > news >正文

P2168 NOI2015 荷马史诗

#算法/哈夫曼树

思路:

显然,这题需要将每个单词换成独立且没有前缀的进制字符串,显然,我们可以联想起来二进制哈夫曼树,我们只需要将二进制转换成我们要求的进制即可,但是,会出现一个问题,如果是二进制,显然,任何数量结点最终都会变成两堆,然后合并成一堆,但是,如果是三进制,四进制…,显然,会出现无法恰好被合并成一堆的情况,那么,这会出现什么情况呢?
以三进制为例
假设有4个结点s1,s2,s3,s4
![[Pasted image 20250514121816.png]]

根据图示,我们会发现s1,s2,s3长度都为2,s4长度都为1
但是,如果我们补充结点s0,使得结点恰好被合并成一堆
![[Pasted image 20250514122151.png]]

我们可以根据图示得出
s1,s2长度为2,s3,s4长度为1
所以,在我们合并之前,需要先判断当前的结点是否能够恰好合并成一堆,如果无法恰好合并成一堆,我们需要补0,使得靠近根节点的结点尽可能多,不会出现空余的地方

1.定义结点

struct node {
//w表示权重ll w;
//h表示深度ll h;
//优先选择权重小的friend bool operator<(node n1, node n2) {
//如果权重相同,为了保证深度最小,优先将深度小的选出来if(n1.w==n2.w){return n1.h>n2.h;}else return n1.w > n2.w;}
}nodes[N];

2.保证结点数量恰好分配成一堆

  for (int i = 0; (n - 1 + i) % (m - 1) != 0; i++) {cnt++;nodes[cnt].w = 0;nodes[cnt].h = 1;pq.push(nodes[cnt]);}

3.寻找最小m堆

 while (pq.size() >= m) {ll w = 0;ll h = -1;for (int i = 1; i <= m; i++) {node tpq = pq.top();//我们每次找到子结点时,就将子节点的权重加起来,方便后序将子节点的深度加1w += tpq.w;pq.pop();h = max(tpq.h, h);}//子节点的所有深度加1,相当于将这些子节点的权重再加一遍sum += w;pq.push({ w,h + 1 });}

完整代码

#include<iostream>#include<string>#include<vector>#include<queue>using namespace std;int n, m;const int N = 1e5 + 30;typedef long long ll;ll cnt;struct node {ll w;ll h;friend bool operator<(node n1, node n2) {if(n1.w==n2.w){return n1.h>n2.h;}else return n1.w > n2.w;}}nodes[N];priority_queue<node>pq;int main(void) {cin >> n >> m;for (int i = 1; i <= n; i++) {cnt++;cin >> nodes[cnt].w;nodes[cnt].h = 1;pq.push(nodes[cnt]);}for (int i = 0; (n - 1 + i) % (m - 1) != 0; i++) {cnt++;nodes[cnt].w = 0;nodes[cnt].h = 1;pq.push(nodes[cnt]);}ll sum = 0;while (pq.size() >= m) {ll w = 0;ll h = -1;for (int i = 1; i <= m; i++) {node tpq = pq.top();w += tpq.w;pq.pop();h = max(tpq.h, h);}sum += w;pq.push({ w,h + 1 });}cout << sum << endl << pq.top().h - 1 << endl;}
http://www.xdnf.cn/news/438805.html

相关文章:

  • Kubernetes排错(十七) :kubelet日志报device or resource busy
  • 【机器人】复现 SG-Nav 具身导航 | 零样本对象导航的 在线3D场景图提示
  • ​​开放传神创始人论道AI未来|“广发证券—国信中数人工智能赛道专家交流论坛“落幕
  • MySQL——九、锁
  • 【Linux】Ext系列文件系统
  • 卷积神经网络全连接层详解:特征汇总、FCN替代与性能影响分析
  • SRM电子采购管理系统:Java+Vue,集成供应商管理,实现采购流程数字化与协同优化
  • PyQt5完整指南:从入门到实践
  • 刘强东 “猪猪侠” 营销:重构创始人IP的符号革命|创客匠人热点评述
  • 如何创建自动工作流程拆分Google Drive中的PDF文件
  • iOS视频编码详细步骤(视频编码器,基于 VideoToolbox,支持硬件编码 H264/H265)
  • 深度学习基础知识
  • RK3588 串行解串板,支持8路GMSL相机
  • 嵌入式Linux Qt开发:1、搭建基于ubuntu18.04的Qt开发环境及测试(解决Qt creator输入法问题)
  • python三方库sqlalchemy
  • 【网络协议】TCP、HTTP、MQTT 和 WebSocket 对比
  • 内存虚拟盘(RAMDisk)是什么?
  • Axure设计之轮播图——案例“一图一轮播”
  • 基于策略的强化学习方法之策略梯度(Policy Gradient)详解
  • 如何高效集成MySQL数据到金蝶云星空
  • TAOCMS漏洞代码学习及分析
  • 嵌入式自学第二十一天(5.14)
  • JVM 与云原生的完美融合:引领技术潮流
  • 【SpringBoot实战指南】集成Easy ES
  • OpenCV实现数字水印的相关函数和示例代码
  • QListWedget控件使用指南
  • 50. Pow(x, n)
  • 网络互联技术深度解析:理论、实践与进阶指南
  • stm32之FLASH
  • C++效率掌握之STL库:map set底层剖析及迭代器万字详解