荷马史诗

荷马史诗

题意:给n个单词出现的次数,然后给个k,让这个单词转换为二进制,然后求总长度最小,以及最大的一个转换后字符串的长度。

题解:我们发现这道题目,要求我们算出哈夫曼编码,也就是最短不重叠前缀的编码,那么我们就可以用上trie字典树的性质配合哈夫曼树进行处理.

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#define ll long long
using namespace std;
struct point 
{
    ll x;
    ll y;    
    friend bool operator < (point a, point b)     
    {   
        if(a.x==b.x)
        return a.y>b.y; 
        return a.x > b.x; 
        
    }
};
priority_queue<point> qu;
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        for(int i=0;i<n;i++)
        {
            point x;
            scanf("%lld",&x.x);
            x.y=0;
            qu.push(x);
        }
        while((qu.size()-1)%(k-1)!=0)
        {
            point x;
            x.x=0;
            x.y=0;
            qu.push(x);
        }
        ll sum=0;
        while(qu.size()!=1)
        {
            ll t=0,deep=-1;
            for(int i=0;i<k;i++)
            {
                point r=qu.top();
                t+=r.x;
                deep=max(deep,r.y);
                qu.pop();
            }
            point e;
            e.x=t;
            e.y=deep+1;
            qu.push(e);
            sum+=t;
        }
        printf("%lld\n%lld\n",sum,qu.top().y);
    }
} 

 

posted @ 2019-07-31 23:09  Ldler  Views(183)  Comments(0Edit  收藏  举报