题目链接:https://vjudge.net/contest/373557#problem/I
题目大意:求 重新编码后的 最短长度 和 重新编码后的 最长字符串的长度
数据结构刚学了Huffman树,比赛就考到了Huffman编码,在这里整理一下。
Huffman树是最优二叉树,这道题相当于最优k叉树,但是又有些不同。
不会Huffman树的可以从百度搜索,这里就不具体讲了。
Huffman树是在队列中挑出最小的两个权值组成一新节点,并放入队列中。
在这道题里面,并不是二进制,而是K进制,所以想要用到Huffman树,必须要满足(n-1)%(k-1)==0,这个条件的意思就是:最后合并的时候肯定能满足只剩k个节点,刚好能合并成最后一个节点。(不行的话,可以自己举几个例子试试)
如果不满足这个条件的话就要把{0,0}代替节点输进去。
这道题还要用到优先队列,我有一条龙服务,不会优先队列的,我博客里面有关于优先队列的单独一篇,下面给链接:https://blog.nowcoder.net/n/ad8e1df876064b0a8a3034b7df74f35d
这里优先队列的应用就是把节点中权值小的放到前面,如果权值一样的话,就把深度小的放到前面。
用一个while循环,直到优先队列中只剩下最后一个元素的时候,结束循环。(这里要注意不是优先队列为空的时候,是优先队列大小为1的时候停止循环)
循环里面就是每k个为一组,把长度值加起来并加到要输出的最终长度值上,把三个的深度求出最大值,结束for循环对输出的最短长度进行优化。
下面是AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stdlib.h>
using namespace std;
struct sss{
long long x,h;
bool operator <(const sss & y) const
{
if(x!=y.x) return x>y.x;
else return h>y.h;
}
}p;
int main()
{
long long n,k,x;
cin >> n >> k;
priority_queue<sss>q;
for (int i=1;i<=n;i++)
{
cin >> x;
q.push({x,0});
}
while((n-1)%(k-1)!=0)
{
n++;
q.push({0,0});
}
long long ans1=0;
long long ans2=0;
while(q.size()>1)
{
long long xx=0;
long long hh=0;
for (int i=1;i<=k;i++)
{
p=q.top();
cout << p.h << " " << p.x << endl;
q.pop();
hh=max(p.h,hh);
xx+=p.x;
}
ans1+=xx;
ans2=max(ans2,hh+1);
q.push({xx,hh+1});
}
cout << ans1 << endl << ans2 << endl;
return 0;
}



京公网安备 11010502036488号