4198: [Noi2015]荷马史诗

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 127  Solved: 80

Description

追逐影子的人,自己就是影子。 ——荷马

Allison 最近迷上了文学。她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的《荷马史诗》。但是由《奥德赛》和《伊利亚特》组成的鸿篇巨制《荷马史诗》实在是太长了,Allison 想通过一种编码方式使得它变得短一些。

一部《荷马史诗》中有 n 种不同的单词,从 1 到 n 进行编号。其中第 i 种单词出现的总次数为 wi。Allison 想要用 k 进制串 si 来替换第 i 种单词,使得其满足如下要求:

对于任意的 1≤i,j≤n,i≠j,都有:si 不是 sj 的前缀。

现在 Allison 想要知道,如何选择 si,才能使替换以后得到的新的《荷马史诗》长度最小。在确保总长度最小的情况下,Allison 还想知道最长的 si 的最短长度是多少?

一个字符串被称为 k 进制字符串,当且仅当它的每个字符是 0 到 k−1 之间(包括 0 和 k−1)的整数。

字符串 Str1 被称为字符串 Str2 的前缀,当且仅当:存在 1≤t≤m,使得 Str1=Str2[1..t]。其中,m 是字符串 Str2 的长度,Str2[1..t] 表示 Str2 的前 t 个字符组成的字符串。

Input

输入文件的第 1 行包含 2 个正整数 n,k,中间用单个空格隔开,表示共有 n 种单词,需要使用 k 进制字符串进行替换。

接下来 n 行,第 i+1 行包含 1 个非负整数 wi,表示第 i 种单词的出现次数。

Output

输出文件包括 2 行。

第 1 行输出 1 个整数,为《荷马史诗》经过重新编码以后的最短长度。
第 2 行输出 1 个整数,为保证最短总长度的情况下,最长字符串 si 的最短长度。

Sample Input

4 2
1
1
2
2

Sample Output

12
2

HINT

用 X(k) 表示 X 是以 k 进制表示的字符串。

一种最优方案:令 00(2) 替换第 1 种单词,01(2) 替换第 2 种单词,10(2) 替换第 3 种单词,11(2) 替换第 4 种单词。在这种方案下,编码以后的最短长度为:

1×2+1×2+2×2+2×2=12
最长字符串 si 的长度为 2。

一种非最优方案:令 000(2) 替换第 1 种单词,001(2) 替换第 2 种单词,01(2) 替换第 3 种单词,1(2) 替换第 4 种单词。在这种方案下,编码以后的最短长度为:

1×3+1×3+2×2+2×1=12
最长字符串 si 的长度为 3。与最优方案相比,文章的长度相同,但是最长字符串的长度更长一些。

对于所有数据,保证 2≤n≤100000,2≤k≤9。
选手请注意使用 64 位整数进行输入输出、存储和计算。

题解:

如果没有想到Huffman就跪了。。
分析题目,发现出现次数其实就是权重,我们要求的就是一种编码方案使得权重×编码长和最小,可以直接套k叉Huffman树乱搞。
类比合并果子,考虑倒着进行编码。从叶子节点开始编码,每次取出最小k个数合成一个x,然后编码长加1(实际上是倒着的,但其实是一样的),再把x扔回去,以此类推。
注意:
可能会有空节点,即可能存在一个节点儿子不足k个,这就需要补零以防出错,常用的判断方法:(n-1)%(k-1),等于0代表是满k叉树。
(因为对于一棵满k叉树,任意节点要么有k个儿子,要么没有儿子,设叶子节点有x个,则(n-x)*k=n-1,推导一下即可)

Code:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
#define LL long long
struct H{LL w; int l;bool operator < (const H &a) const {if (w!=a.w) return a.w<w;return a.l<l;}
};
priority_queue<H> h;
int n,k,nn; LL ans=0;
int in(){int x=0; char ch=getchar();while (ch<'0' || ch>'9') ch=getchar();while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x;
}
LL Lin(){LL x=0; char ch=getchar();while (ch<'0' || ch>'9') ch=getchar();while (ch>='0' && ch<='9') x=x*10+(LL)(ch-'0'),ch=getchar();return x;
}
int main(){n=in(),k=in(); nn=n;for (int i=1; i<=n; i++){LL x=Lin();h.push((H){x,1});}if ((n-1)%(k-1)) nn+=(k-1)-((n-1)%(k-1));for (int i=n+1; i<=nn; i++)h.push((H){0,1});while (nn>1){LL s1=0; int s2=0;for (int i=1; i<=k; i++){H x=h.top(); h.pop();s1+=x.w; s2=max(s2,x.l);}ans+=s1; nn-=(k-1);h.push((H){s1,s2+1});}printf("%lld\n%d\n",ans,h.top().l-1);return 0;
}

【Huffman树】【贪心】【NOI 2015】【bzoj 4198】荷马史诗相关推荐

  1. [Huffman树] aw149. 荷马史诗(哈夫曼模型+贪心)

    文章目录 1. 题目来源 2. 题目解析 1. 题目来源 链接:149. 荷马史诗 2. 题目解析 k叉哈夫曼树问题. n 个叶子节点合并成 1 个点,总共合并减少 n-1 个点,每次合并都会减少 ( ...

  2. [NOI 2015]荷马史诗

    Description 追逐影子的人,自己就是影子. --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由& ...

  3. (HYSBZ - 4198)荷马史诗

    (HYSBZ - 4198)荷马史诗 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 1376 Solved: 725 Description 追逐影子 ...

  4. 荷马史诗【k叉哈夫曼树】

    题目描述 追逐影子的人,自己就是影子. --荷马 达达最近迷上了文学. 她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>. 但是由<奥德赛>和 ...

  5. 周末狂欢赛4(1-02E. JM的西伯利亚特快专递,寿司晚宴,荷马史诗)

    文章目录 T1:1-02E. JM的西伯利亚特快专递 题目 题解 code T2:寿司晚宴 题目 题解 code T3:荷马史诗 题目 题解 code T1:1-02E. JM的西伯利亚特快专递 题目 ...

  6. NOI2015 Day2 T1 荷马史诗(洛谷P2168)

    题目描述 追逐影子的人,自己就是影子 --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛&g ...

  7. 算法进阶指南:0x17:荷马史诗

    原题链接 追逐影子的人,自己就是影子. --荷马 达达最近迷上了文学. 她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>. 但是由<奥德赛>和 ...

  8. jzoj 6012.【NOIP2019模拟1.25A组】荷马史诗 dp

    Description 追逐影子的人,自己就是shadow. --荷马 Shadow 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但 ...

  9. 洛谷P2168 荷马史诗 [NOI2015]

    题目描述 追逐影子的人,自己就是影子 --荷马 Allison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛&g ...

最新文章

  1. [笔记]java-package
  2. POJ - 2385 Apple Catching (dp)
  3. C#匿名对象在其它方法体内怎么取到相应的值(不想建立对应的类并转化的情况下)?...
  4. Pycharm 加载pygame解决方案
  5. 2013-2-19 Android之ActionBar学习(转)
  6. [翻译] KGModal
  7. 将Office2010版EXCEL文件保存为2007版.XLS文件格式体积巨增解决方法
  8. QA:golang redis协议同时写入报错
  9. 回顾 2018: 革新的一年
  10. dsoframer java_dsoframer控件动态加载
  11. 使用虚拟机镜像文件导入部署openGauss
  12. PHP使用PHPMailer实现发送qq邮箱
  13. java 新特性-TWR(Try-with-resources)
  14. 什么是幂等,什么情况下需要幂等,如何实现幂等
  15. 普通话测试app怎么样可以不交钱_如何说普通话才算标准?
  16. ug8.5的java下载_ug8.5下载 UG NX8.5正式版 64位 官方版 下载-脚本之家
  17. 软件测试工程师春招薪资20K+,BAT校招薪资表出炉!学弟学妹们看齐...
  18. 长处比短板更容易困住你,读《能力陷阱》有感
  19. 痞子衡嵌入式:在i.MXRT1060-EVK上利用memtester程序给SDRAM做压力测试
  20. 通过python构建一个区块链来学习区块链

热门文章

  1. USB 概述及协议基础
  2. hp380g10服务器安装系统,hp380G10服务器安装centos6.9和显卡驱动-Go语言中文社区
  3. 计算机中考在线评分模拟卡,TOP30广西南宁市2016届中考权威预测模拟数学试卷一解析版.doc文档免费在线阅读(模版2)...
  4. 数据库系统概论(第五版)复习资料
  5. 【BLE】CC2541之串口收发
  6. 用python爬取网易云评论10w+的歌曲名_Python爬取网易云音乐评论热门歌曲和ID
  7. MSELoss详解+避坑指南
  8. 业务流水号规则生成组件
  9. python实现坐标系转换_(数据科学学习手札60)用Python实现WGS84、火星坐标系、百度坐标系、web墨卡托四种坐标相互转换...
  10. 前端参数效验防止sql注入的方法