zoukankan      html  css  js  c++  java
  • 【BZOJ 4198】[Noi2015]荷马史诗 哈夫曼编码

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

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

    他的实际应用就是哈夫曼编码,拓展就是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=100010;
    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==0;}
      inline V top(){return k[1];}
      inline int size(){return len;}
      inline void pop(){
        k[1]=k[len--];register int now=1;
        while(now<=(len>>1)){
          int next=now<<1;
          if(next<len&&k[next|1]<k[next])next|=1;
          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!=1&&k[now]<k[now>>1])
          std::swap(k[now],k[now>>1]),now>>=1;
      }
    }
    int n,k;
    LL ans;
    int main(){
      scanf("%d%d",&n,&k);LL x;
      for(int i=1;i<=n;++i)
        scanf("%lld",&x),HoN push(make(x,1));
      if(k!=2&&n%(k-1)!=1){
        if(n%(k-1)==0)HoN push(make(0,1)),++n;
        else{
          for(int i=1;i<=k-(n%(k-1));++i)
            HoN push(make(0,1));
          n+=n%(k-1);
        }
      }
      int m=k==2?n-1:n/(k-1);
      int max;HoN V use;
      while(m--){
        x=0,max=0;
        for(int i=1;i<=k;++i)
          use=HoN top(),HoN pop(),x+=use.val,max=std::max(max,use.deep);
        ans+=x,HoN push(make(x,max+1));
      }
      printf("%lld
    %d",ans,HoN top().deep-1);
      return 0;
    }
  • 相关阅读:
    Linux基本权限管理
    Spring JMS
    消息中间件 ActiveMQ的简单使用
    Ionic slides 轮播图
    Spring 3 MVC and XML example
    Java 数组
    Java String类
    Java static 使用
    http://blog.csdn.net/huang_xw/article/details/7090173
    http://blog.chinaunix.net/uid-20577907-id-3519578.html
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7634070.html
Copyright © 2011-2022 走看看