问题描述
给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。在这里,我们给出哈夫曼树的构造过程如下。 给出一组数{qi}={q0, q1, …, qn-1},用这组数构造哈夫曼树的过程: 1. 找到{qi}中最小的两个数然后将其删除再将其和加入到{qi},如设为qa和qb,将qa和qb从{qi}中删除掉,然后将它们的和加入到{qi}中。这个过程的浪费的时间记为qa + qb。 2. 重复步骤1,直到{qi}中只剩下一个数。 在上面的操作过程中,把所有浪费的时间相加,就得到了构造哈夫曼树的总时间。 本题任务:对于给定的一个数列,现在请你求出用该数列构造哈夫曼树的总时间。 例如,对于数列{qi}={ 2,3,5,8,9},哈夫曼树的构造过程如下:
1.找到2,3。将其删除后再将和5加入,得到{5,5,8,9}。该过程所浪费时间为5。
2.找到5,5。将其删除后再将和10加入,得到{8,9,10}。该过程所浪费时间为10。
3.找到8,9。将其删除后再将和17加入,得到{10,17}。该过程所浪费时间为17。
4.找到10,17。将其删除后再将和27加入,得到{27}。该过程所浪费时间为27。
5. 现在,数列中只剩下一个数27,构造哈夫曼树的过程结束,所用总时间为5+10+17+27=59。
输入
输入的第一行包含一个正整数n(n<=100)。 接下来是n个正整数,表示q0, q1, …, qn-1,每个数不超过1000。
输出
输出用数列{qi}构造哈夫曼树的总时间。
输入范例
5 5 3 8 2 9
输出范例
59
AC代码:
#include<stdio.h>
void sort(int b[],int n)
{
int i;
int j;
int t;
for(i=0;i<n;i++){
for(j=i+1;j<n;j++){
if(b[i]>b[j]){
t=b[i];
b[i]=b[j];
b[j]=t;
}
}
}
}
int main()
{
int a[101];
int i;
int n;
int time;
while(scanf("%d",&n)!=EOF){
time=0;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,n);
for(i=1;i<n;i++){
time=time+a[i]+a[i-1];
a[i]=a[i]+a[i-1];
a[i-1]=0;
sort(a,n);
}
printf("%d\n",time);
}
return 0;
}