题目描述

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

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个字符组成的字符串。

输入输出格式

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

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

输出格式:
输出包括 2 行。

第 1 行输出 1 个整数,为《荷马史诗》经过重新编码以后的最短长度。

第 2 行输出 1 个整数,为保证最短总长度的情况下,最长字符串 si 的最短长度。

输入输出样例

输入样例#1:
4 2
1
1
2
2
输出样例#1:
12
2
输入样例#2:
6 3
1
1
3
3
9
9
输出样例#2:
36
3

说明

【样例说明 1】

用 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】

一种最优方案:令 000(3) 替换第 1 种单词,001(3) 替换第 2 种单词,01(3) 替换第 3 种单词, 02(3) 替换第 4 种单词, 1(3) 替换第 5 种单词, 2(3) 替换第 6 种单词。

【提示】

选手请注意使用 64 位整数进行输入输出、存储和计算。

【时限1s,内存512M】


题解

这是我听了Huffman树之后写的题,老师也说了思路了,所以我只是按照着思路做而已。
大家都知道最佳二叉树吧,也就是Huffman树(不知道的自己学,或者百度),然后这题,就是一个最佳k叉树。
很多人会想到每次选k个合并,再塞回去,可惜这是错的。为什么?很简单,拿着第二组样例手玩一下,就发现为什么错了:因为最后一次合并没有合并够k个,所以只要把第一次的某几个放上来,就会得到更优的解。
再回来看合并的过程,可以发现,每一次合并都会使总点数减少k-1个,除去合并完最后剩下的那个,用其他的点的总数来mod(k-1),所得的答案就是第一次合并应该减少的点数,做完第一次合并后,就可以用和Huffman树相似的方法来求解了。
另一种方法,可以发现,只要(n-1)mod(k-1)==0,就可以按照Huffman树的方法来求解,这样,我们就可以补充若干个虚点,使上式成立,再正常求解。
接下来,它还要求在确保总长度最小的情况下的最长的si的最短长度是多少。要求这个最小值,就要每一步合并时,增加一个次关键值,当权值相等时,比较节点深度,较小的排在前面。这样,最后合并剩下的那个点的深度再-1就是答案。(因为深度1上没有点,不算在长度里)
总的来说,这题真的是近几年NOI里最简单的题了。
下来贴代码:


#include<bits/stdc++.h>
#define For(i,j,k) for(int i=j;i<=k;i++)
#define ull long long
using namespace std;
typedef pair<ull,ull> pii;
int n,k;
ull s[100001];
priority_queue<pii,vector<pii>,greater<pii> > q;
int main(){scanf("%d %d",&n,&k);For(i,1,n){scanf("%lld",&s[i]);q.push(pii(s[i],1));}int first=(n-1)%(k-1);ull ans=0;ull num=0;int Num=0;if(first!=0){Num=k-1-first;For(i,1,Num){q.push(pii(0,1));}}Num+=n;while(Num!=1){ull val=0;ull dep=1;For(i,1,k){pii p=q.top();q.pop();dep=max(dep,p.second+1);val+=p.first;}ans+=val;q.push(pii(val,dep));Num-=k;Num++;}printf("%lld\n",ans);printf("%lld",q.top().second-1);return 0;
}

转载于:https://www.cnblogs.com/stone41123/p/7581294.html

NOI2015 Day2 T1 荷马史诗(洛谷P2168)相关推荐

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

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

  2. 【洛谷P2168】荷马史诗

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

  3. 洛谷 P2168 荷马史诗(抄)

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

  4. [NOI2015]荷马史诗【哈夫曼编码】

    [NOI2015]荷马史诗 推荐一篇题解 (感觉自己讲不清楚所以不如直接粘题解) 观察之后发现这就是哈夫曼编码,于是按照编码方式构造即可. #include <bits/stdc++.h> ...

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

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

  6. ajax荷马史诗,荷马史诗(8)

    <奥德赛>(Odyssey) 奥德修斯的希腊文原意是"麻烦":他既带给别人麻烦,自己也遭遇麻烦 <埃阿斯和卡珊德拉>(Ajax and Cassandra) ...

  7. 【Huffman树】【贪心】【NOI 2015】【bzoj 4198】荷马史诗

    4198: [Noi2015]荷马史诗 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 127 Solved: 80 Description 追逐影子的 ...

  8. [NOI 2015]荷马史诗

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

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

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

最新文章

  1. /sys目录下其他几个目录的生成
  2. 主流微服务全链路监控系统之战
  3. adc0808温度换算公式_温湿度传感器的三种模拟量换算关系
  4. 2019年DevOps实践最有价值的技能Top 8
  5. C# 中居然也有切片语法糖,太厉害了
  6. 命令行编译java项目_命令行编译运行java工程(转)
  7. Qt 字符串QString arg()用法总结
  8. 读后感《习惯的力量》
  9. python元组索引_Python—范围元组中的元素索引
  10. python自动获取邮件数据_Python 获取测试报告内容并发送邮件
  11. 【java】Java实现异步调用方法(jdk1.8)
  12. OpenShift 4 - Fedora CoreOS (2) - 准备 Fedora CoreOS 安装环境的三个工具
  13. python用正方形画圆_Python 用turtle实现用正方形画圆的例子
  14. Response.Redirect和Server.Transfer的区别
  15. Leetcode142. Linked List Cycle II环形链表2
  16. u盘安全弹出有什么用?数据丢失还能恢复吗
  17. iphone帧数测试软件,GFXBench 5.0推出全新测试 苹果A11也只跑17fps
  18. mysql不同分数的人数,mysql如何统计每个专业分数段的人数
  19. Java现在好找工作吗?
  20. Logback日志配置和简单使用

热门文章

  1. 我的Python学习之路(2)
  2. win7 访问共享文件错误代码: 0x80070035
  3. 成功解决numpy.linalg.LinAlgError: SVD did not converge
  4. java static 并发_Java static并发问题
  5. 数据治理系列文章:(2)数据治理的发展与演进
  6. jQuery入口函数
  7. 在python中month函数的用法_Python代码中calendar.weekday(year,month,day)函数起什么作用呢?...
  8. wordpress主题开发核心知识
  9. Apache Sentry详细讲解
  10. androidx86 换4.9kernel 踩坑