题目链接:点击打开链接
给定哈夫曼树的n个叶子节点距离根的距离
问:
文本串至少要多少个字符可以建出这样的哈夫曼树
思路:
对于第i层的叶子节点,赋值为i+1层的节点中权值最大的点这种情况下字符数最少
注意的是如果i+1层没有叶子节点也要合并一下。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
template <class T>
inline bool rd(T &ret) {
char c; int sgn;
if(c=getchar(),c==EOF) return 0;
while(c!='-'&&(c<'0'||c>'9')) c=getchar();
sgn=(c=='-')?-1:1;
ret=(c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
template <class T>
inline void pt(T x) {
if (x <0) {
putchar('-');
x = -x;
}
if(x>9) pt(x/10);
putchar(x%10+'0');
}
using namespace std;
typedef long long ll;
const int N = 55;
priority_queue<ll> q1, q2;
int a[N], n;
bool cmp(const int x, const int y) {
return x>y;
}
void work() {
while(q1.size()) q1.pop();
while(q2.size()) q2.pop();
for(int i = 0, x; i < n; i ++) {
scanf("%d", &x);
a[x] ++;
}
ll m = 1, ans = 0;
for(int i = 50; i > 0; i --) {
while(a[i] > 0) {
q1.push(m);
ans += m;
a[i] --;
}
ll x;
while(q1.size() > 1) {
// printf("%d ", q1.top());
m = max(m, q1.top());
x = q1.top();q1.pop();
// printf("%d\n", q1.top());
m = max(m, q1.top());
x += q1.top();q1.pop();
q2.push(x);
}
if(q1.size()) {
m = max(m, q1.top());
}
// printf(" %d\n", m);
while(q2.size()) {
q1.push(q2.top());
q2.pop();
}
// printf("%d, %d\n", i, m);
}
cout << ans << endl;
}
int main(){
while(cin>>n)
work();
return 0;
}