acwing 149. 荷马史诗 [哈夫曼树]

2023-12-14 14:10

本文主要是介绍acwing 149. 荷马史诗 [哈夫曼树],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

追逐影子的人,自己就是影子。 ——荷马
达达最近迷上了文学。
她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的《荷马史诗》。
但是由《奥德赛》和《伊利亚特》组成的鸿篇巨制《荷马史诗》实在是太长了,达达想通过一种编码方式使得它变得短一些。
一部《荷马史诗》中有 n 种不同的单词,从 1 到 n 进行编号。其中第 i 种单词出现的总次数为 wi。
达达想要用 k 进制串 si 来替换第 i 种单词,使得其满足如下要求:
对于任意的 1≤i,j≤n,i≠j,都有:si 不是 sj 的前缀。
现在达达想要知道,如何选择 si,才能使替换以后得到的新的《荷马史诗》长度最小。
确保总长度最小的情况下,达达还想知道最长的 si 的最短长度是多少?
一个字符串被称为 k 进制字符串,当且仅当它的每个字符是 0 到 k−1 之间(包括 0 和 k−1)的整数。
字符串 Str1 被称为字符串 Str2 的前缀,当且仅当:存在 1≤t≤m,使得 Str1=Str2[1…t]。
其中,m 是字符串 Str2 的长度,Str2[1…t] 表示 Str2 的前 t 个字符组成的字符串。
输入格式
输入文件的第 1 行包含 2 个正整数 n,k,中间用单个空格隔开,表示共有 n 种单词,需要使用 k 进制字符串进行替换。
第2~n+1 行:第 i+1 行包含 1 个非负整数 wi,表示第 i 种单词的出现次数。
输出格式
输出文件包括 2 行。
第 1 行输出 1 个整数,为《荷马史诗》经过重新编码以后的最短长度。
第 2 行输出 1 个整数,为保证最短总长度的情况下,最长字符串 si 的最短长度。
数据范围
2≤n≤100000,
2≤k≤9
输入样例:
4 2
1
1
2
2
输出样例:
12
2

大致思路就是模拟建一颗哈夫曼数;
注意要把底端缺的节点补上,例如k=3,可以看出底端节点n一定(k-1)|(n-1)
在这里插入图片描述

#include <bits/stdc++.h>
using <

这篇关于acwing 149. 荷马史诗 [哈夫曼树]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/492829

相关文章

【AcWing】851. 求最短路

spfa算法其实是对贝尔曼福特算法做一个优化。 贝尔曼福特算法会遍历所有边来更新,但是每一次迭代的话我不一定每条边都会更新,SPFA是对这个做优化。 如果说dist[b]在当前这次迭代想变小的话,那么一定是dist[a]变小了,只有a变小了,a的后继(b)才会变小。 用宽搜来做优化,用一个队列,队列里边存的就是所有变小了的结点(队列里存的是待更新的点)。 基本思路就是我更新过谁,我再拿

【AcWing】852. spfa判断负环

#include<iostream>#include<algorithm>#include<cstring>#include<queue>using namespace std;const int N= 1e5+10;int n,m;int h[N],w[N],e[N],ne[N],idx;int dist[N],cnt[N];//cnt存最短路径的边数bool st[N];v

数据结构-非线性结构-树形结构:有序树 ->二叉树 ->哈夫曼树 / 霍夫曼树(Huffman Tree)【根据所有叶子节点的权值构造出的 -> 带权值路径长度最短的二叉树,权值较大的结点离根较近】

哈夫曼树概念:给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。 哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。 一、相关概念 二叉树:每个节点最多有2个子树的有序树,两个子树分别称为左子树、右子树。有序的意思是:树有左右之分,不能颠倒 叶子节点:一棵树当中没有子结点的结点称为叶子

AcWing 282. 石子合并

必看的视频讲解↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【E28【模板】区间DP 石子合并——信息学竞赛算法】 合并过程总开销等于红色数字总和,可以理解为花费的总体力! f数组的含义是f【i】【j】是从第i堆石子开始到第j堆石子的花费体力最小值 如何理解三层for呢? 第一层for是控制区间长度len,第二层for是控制区间起点位置i,第三层for是控制区间

AcWing 897. 最长公共子序列

动态规划就是多见识应用题就完事儿了,也没有什么好说的。 讲解参考: 【E05 线性DP 最长公共子序列】 #include<iostream>#include<algorithm>#define N 1010using namespace std;char a[N],b[N];int n,m;int f[N][N];int main(){cin >> n >> m >> a

AcWing 2. 01背包问题

一定要看的视频讲解:↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 【E08【模板】背包DP 01背包——信息学竞赛算法】 i表示放入i个物品,j表示第j个物品,用于访问体积v【j】 #include <iostream>#include <algorithm>using namespace std;const int N = 1010;int n, m;int v[N]

哈夫曼树例子

五个字符:a,b,c,d,e,它们出现的的频率为8,14,10,4,18构造相应的哈夫曼树,求出每个字符的哈夫曼编码: 哈夫曼树:54/ \22 32/ \ / \c10 12 b14 e18/ \d4 a8哈夫曼编码:a:011 b:10 c:00 d:010 e:11

Python习题 149:用 zip 将姓名和成绩结合成字典

(编码题)有两个列表,一个包含学生的姓名 students,另一个包含对应的考试分数 scores。请使用 zip 函数,创建一个字典,将学生姓名与对应的分数关联起来,同时去除小于60分的学生。 students = [‘Alice’, ‘Bob’, ‘Charlie’, ‘David’, ‘Eva’] scores = [85, 58, 78, 34, 88] 输出 {‘Alice’: 8

合并果子之哈夫曼树——优先队列解决哈夫曼

树-堆结构练习——合并果子之哈夫曼树 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Submit  Status Description 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。 每一次合并,多多可以把两堆

九度OJ-1172-哈夫曼树

由于建立的哈夫曼树不唯一,所以机试多考察哈夫曼树的带权路径长度和,如此题。此问题最终转化为利用堆模拟建树过程,求出非叶节点的权值和(=该哈夫曼树的带权路径长度和)。(无需作出哈夫曼树的具体结构体)   收获如下:   ①关于哈夫曼树:该树非叶节点的权值和=该哈夫曼树的带权路径长度和   ②关于堆排序:堆排序建堆O(n*logn),初始堆完成后,每次重新调整只需O(logn)(树深),故是