重编码-K
背景
小粽学习了哈夫曼树之后,自己设计了贪心算法,用两个队列就过掉了《重编码》这道题。
小粽想:那堆的算法有什么用呢?为了解决小粽的疑惑,邓老师委托小莉命制了这道题目……
描述
有一篇文章,文章包含 n
种单词,单词的编号从 1 至 n,第 i 种单词的出现次数为 wi
。
现在,我们要用一个 k
进制串(即只包含 0,1,...,k−1 的串) si 来替换第 i 种单词,使其满足如下要求:对于任意的 1≤i<j≤n,都有 si 不是 sj
的前缀(这个要求是为了避免二义性)。
你的任务是对每个单词选择合适的 sj
,使得替换后的文章总长度(定义为所有单词出现次数与替换它的 k
进制串的长度乘积的总和)最小。求这个最小长度。
字符串 S1
(不妨假设长度为 n)被称为字符串 S2 的前缀,当且仅当:S2 的长度不小于 n,且 S1 与 S2 前 n
个字符组组成的字符串完全相同。
输入格式
第一行两个整数 n
和 k
。
第 2 行到第 n+1
行,第 i+1 行包含一个正整数 wi,表示第 i
种单词的出现次数。
输出格式
表示整篇文章重编码后的最短长度
输入样例1
5 3
1
3
5
10
3
输出样例1
29
样例2
点此下载。
限制
对于 100% 的数据,满足 1≤n≤3×105,2≤k≤10,1≤wi≤109
;
对于 40% 的数据,满足 n≤3000
;
对于 35% 的数据,满足 k=2
。
提示
[贪心思路与重编码题目相同。需要思考的是:如何让最后构建的哈夫曼树为满 k
叉树呢?]
为了帮助大家完成题目,我们提供了只包含了输入输出功能的程序模板,也提供了含有算法的大部分实现细节的程序。
你可以根据自己的实际情况,在这些程序的基础上进行作答,或不参考这些程序,这将与你的得分无关。
这些程序可以从【这里】下载。
特别提醒:对于 Java 语言,在提交时请删除程序中的所有中文字符,否则可能无法通过编译。