luoguP2168 [NOI2015]荷马史诗 哈夫曼树

如果不会哈夫曼树理论的话这题很难做出来吧...    

如果 K=2,就可以根据合并果子那样去构造.  

然后 K>2 的话就构造 k 叉哈夫曼树,如果不满足 $(n-1) \% (k-1)$ 的话就自动补一些进去. 

code: 

#include <bits/stdc++.h>   
#define ll long long  
#define N 100008 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
int n,k;     
ll a[N]; 
struct data { 
    ll w,h;   
    data(ll w=0,ll h=0):w(w),h(h){}  
    bool operator<(const data b) const 
    {
        return w==b.w?h>b.h:w>b.w;  
    }
};  
priority_queue<data>q; 
int main() 
{ 
    // setIO("input");    
    int x,y,z,det=0; 
    scanf("%d%d",&n,&k);        
    for(int i=1;i<=n;++i)  scanf("%lld",&a[i]),q.push(data(a[i],1));       
    if((n-1)%(k-1)) det=k-1-(n-1)%(k-1);            // 补的节点           
    for(int i=1;i<=det;++i) q.push(data(0,1));   
    det+=n;    
    ll ans=0; 
    while(det>1) 
    {
        ll tmp=0,maxh=0;   
        for(int i=1;i<=k;++i) 
            tmp+=q.top().w,maxh=max(maxh,q.top().h),q.pop();   
        ans+=tmp; 
        q.push(data(tmp,maxh+1));      
        det-=k-1; 
    }     
    printf("%lld\n%lld\n",ans,q.top().h-1);     
    return 0; 
}

  

posted @ 2020-06-11 09:18  EM-LGH  阅读(153)  评论(0编辑  收藏  举报