合并果子加强版.......

哈夫曼树是一种特别的贪心算法,它的作用是使若干个点合并成一棵树,每次合并新建一个节点连接两个合并根并形成一个新的根,使叶子节点的权值乘上其到根的路径长的和最短(等价于每次合并的代价是合并根的权值和,求最小代价)。实现过程就是每次合并权值最小的两个节点,具体一下就是建个森林,每次取最小的两个然后权值加和再放入,重复。

他的实际应用就是哈夫曼编码,拓展就是k叉(本题),对于k叉也就是k进制,如果叶子节点不是1+(k-1)*x的形式,那么就加权值为0的点使他变成此种形式,不能到最后一次再加,那样做不是最优树。

关于哈夫曼编码有静态(本题)和动态,并不会动态......

具体实现的话,工程里是循环找最小,oi里是优先队列。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define HoN Heap::
#define make(a,b) ((Heap::V){(a),(b)})
typedef long long LL;
const int N=;
namespace Heap{
struct V{
LL val;int deep;
inline friend bool operator <(V a,V b);
}k[N];
int len;
inline bool operator <(V a,V b){
return a.val<b.val||(a.val==b.val&&a.deep<b.deep);
}
inline bool empty(){return len==;}
inline V top(){return k[];}
inline int size(){return len;}
inline void pop(){
k[]=k[len--];register int now=;
while(now<=(len>>)){
int next=now<<;
if(next<len&&k[next|]<k[next])next|=;
if(k[now]<k[next])return;
std::swap(k[now],k[next]),now=next;
}
}
inline void push(V key){
k[++len]=key;register int now=len;
while(now!=&&k[now]<k[now>>])
std::swap(k[now],k[now>>]),now>>=;
}
}
int n,k;
LL ans;
int main(){
scanf("%d%d",&n,&k);LL x;
for(int i=;i<=n;++i)
scanf("%lld",&x),HoN push(make(x,));
if(k!=&&n%(k-)!=){
if(n%(k-)==)HoN push(make(,)),++n;
else{
for(int i=;i<=k-(n%(k-));++i)
HoN push(make(,));
n+=n%(k-);
}
}
int m=k==?n-:n/(k-);
int max;HoN V use;
while(m--){
x=,max=;
for(int i=;i<=k;++i)
use=HoN top(),HoN pop(),x+=use.val,max=std::max(max,use.deep);
ans+=x,HoN push(make(x,max+));
}
printf("%lld\n%d",ans,HoN top().deep-);
return ;
}

最新文章

  1. cxf设置代理访问webservice接口
  2. OpenGL 多视图与截屏
  3. Redis系列-冷知识
  4. Linux sed 批量替换多个文件中的字符串
  5. java serializable深入了解
  6. bzoj 3037 贪心
  7. centOS 6.4 vsftpd 安装配置
  8. Ext入门的第一个程序(1)
  9. zxing源码分析——QR码部分
  10. Java中的位运算符、移位运算
  11. HDU 1272 小希的迷宫(乱搞||并查集)
  12. MediaPlayer的错误列表速查(android)
  13. linux之scp
  14. java 整型数组基本排序,冒泡,快速选择,插入,归并
  15. DNS:域名系统
  16. Mybatis动态SQL单一基础类型参数用if标签
  17. Qt之QDomDocument操作xml文件-模拟ini文件存储
  18. vue定义全局组件
  19. #WEB安全基础 : HTTP协议 | 0x11 HTTP的分块传输模块
  20. Docker在Windows上运行NetCore系列(一)使用命令控制台运行.NetCore控制台应用

热门文章

  1. scrapy框架爬取笔趣阁完整版
  2. Java学习笔记十三:Java中的类和对象
  3. Java学习笔记五:Java中常用的运算符
  4. 017---Django的中间件解决跨域
  5. Git 克隆指定分支代码
  6. R语言学习笔记(十二):零碎知识点(31-35)
  7. R语言学习笔记(四):apply,sapply,lapply,tapply,vapply以及mapply的用法
  8. 封装一个ExcelHelper,方便将Excel直接转成Datatable对象
  9. 在编程的时候,NotePad++ 中闪烁的光标突然有竖着闪烁的编程蓝色下划线闪烁的--小技巧告诉你-费元星
  10. 通过repcached实现memcached主从复制