首页 > 其他 > 详细

贪心法之K叉哈夫曼树

时间:2018-09-13 23:01:54      阅读:223      评论:0      收藏:0      [点我收藏+]

NOI2015荷马史诗

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

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

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

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

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

 1 #include <bits/stdc++.h>
 2 using namespace std; 
 3 
 4 #define ll long long
 5 
 6 ll n,k,ans;
 7 
 8 struct node{
 9     ll val,dep;
10     node(){}
11     node(ll _,ll __){val=_,dep=__;}
12 }tmp;
13 
14 bool operator <(node x,node y){return x.val>y.val||(x.val==y.val&&x.dep>y.dep);}
15 
16 priority_queue<node> q;
17 
18 ll readin()
19 {
20     ll x=0;char ch=getchar();
21     while(ch<0||ch>9) ch=getchar();
22     while(ch>=0&&ch<=9) x=x*10+(ll)(ch-0),ch=getchar();
23     return x;
24 }
25 
26 void work()
27 {
28     while(n>1){
29         ll maxd=0,tot=0;
30         for(ll i=1;i<=k;i++){
31             tmp=q.top();q.pop();
32             tot+=tmp.val;
33             maxd=max(maxd,tmp.dep);
34         }  
35         q.push(node(tot,maxd+1));
36         ans+=tot;n-=k-1;
37     }
38     printf("%lld\n%lld\n",ans,q.top().dep-1);
39 }
40 
41 void init()
42 {
43     n=readin();k=readin();
44     for(ll i=1;i<=n;i++) q.push(node(readin(),1));
45     ll remain=(n-1)%(k-1);
46     if(remain!=0) remain=k-1-remain,n+=remain;
47     for(ll i=1;i<=remain;i++) q.push(node(0,1));
48 }
49 
50 int main()
51 {
52     init();
53     work();
54     return 0;
55 }

 

贪心法之K叉哈夫曼树

原文:https://www.cnblogs.com/aininot260/p/9643763.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!