据木头问题
首先看过题目之后,即可确定是Huffman树来做,本以为挺容易实现。结果发现一波三折。
1.理解Huffman树的构造方法,但是在具体实现上遇到了难题,涉及到排序和插入,算法功底薄弱,只想到了用链表来做,结果提交的时候总是超时,发现插入时是一个一个往后进行比较,算法效率很低。无奈上网上找找其他人怎么做的,发现很多人说到用堆排序,然后就去学堆排序,发现确实很适合这个题目。
2.最后花费的总和。本来已经考虑到可能数很大,简单的考虑最大值即每个块的最大长度,乘以块的最大个数。所以用的long,提交发现错误,然后把树画出来,发现一个块不止算了一遍,然后用long long 类型,提交成功。
3.坐该题时有Huffman树和堆的概念,最主要的应该理解其思想,做到灵活运用。我还真的构造出树和堆的结构,发现真实够傻,对算法理解还是太浅。
代码
#include<iostream>
using namespace std;
void CreatSmallHeap(int *r,int num);
void HeapAdjust(int *r,int s,int num);
int main()
{
int *plank;
int i;
long long sum=0;
int planks;
int newnode=0;
cin>>planks;
plank=new int[planks+1];
for(i=1;i<=planks;i++)
cin>>plank[i];
CreatSmallHeap(plank,planks);
while(planks>1)
{
newnode=plank[1];
plank[1]=plank[planks--];
HeapAdjust(plank,1,planks);
newnode+=plank[1];
plank[1]=newnode;
HeapAdjust(plank,1,planks);
sum+=newnode;
}
cout<<sum;
delete [] plank;
return 0;
}
void CreatSmallHeap(int *r,int num)
{
int i;
for(i=num/2;i>=1;i--)
HeapAdjust(r,i,num);
}
void HeapAdjust(int *r,int s,int num)
{
int j,temp;
temp=r[s];
for(j=2*s;j<=num;j=j*2)
{
if(j<num&&r[j]>r[j+1])
j++;
if(temp<r[j])
break;
r[s]=r[j];
s=j;
}
r[s]=temp;
}