标签:25 哈夫曼 int 牧场 木头 son fa Heap Data
4-4-哈夫曼树 修理牧场 (25分)农夫要修理牧场的一段栅栏,他测量了栅栏,发现需要N块木头,每块木头长度为整数Li个长度单位,于是他购买了一条很长的、能锯成N块的木头,即该木头的长度是Li的总和。
但是农夫自己没有锯子,请人锯木的酬金跟这段木头的长度成正比。为简单起见,不妨就设酬金等于所锯木头的长度。例如,要将长度为20的木头锯成长度为8、7和5的三段,第一次锯木头花费20,将木头锯成12和8;第二次锯木头花费12,将长度为12的木头锯成7和5,总花费为32。如果第一次将木头锯成15和5,则第二次锯木头花费15,总花费为35(大于32)。
请编写程序帮助农夫计算将木头锯成N块的最少花费。
输入格式:
输入首先给出正整数N(≤),表示要将木头锯成N块。第二行给出N个正整数(≤),表示每段木块的长度。
输出格式:
输出一个整数,即将木头锯成N块的最少花费。
输入样例:
8
4 5 1 2 1 3 1 1
输出样例:
49
解题思路
显然这是一道,哈夫曼树
就是应用堆的操作,很基础的堆的插入删除
众所周知,堆是一个完全二叉树
插入:在尾部插入,再比较父子节点的大小关系,进行调整堆
删除:取出堆顶之后,将最后一个元素补在堆顶,再进行调整堆
简单理解题意就是一个逆向思维,哈夫曼树的正操作过程
实现不难,熟练就行
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; const int Min=0; const int Max=10000000; typedef struct Node* Heap; struct Node{ int* Data; int size; }; Heap Creatheap(int n){ Heap H=(Heap)malloc(sizeof(struct Node)); H->Data=(int*)malloc(2*(n+1) * sizeof(int)); H->size=0; H->Data[0]=Min;//设置哨兵 return H; } int ans; Heap Insert(Heap H,int n){ int fa=++H->size; for(;H->Data[fa/2]>n;fa/=2){ H->Data[fa]=H->Data[fa/2]; } H->Data[fa]=n; return H; } int DeleteMin (Heap H){ int fa,son; int sma=H->Data[1]; int x=H->Data[H->size--]; for(fa=1;fa*2<= H->size;fa=son){ son=fa*2; if(son!=H->size){ if(H->Data[son] > H->Data[son+1])son++; } if(x< H->Data[son])break;//比他的两个儿子都小 else H->Data[fa]=H->Data[son]; } H->Data[fa]=x; return sma; } int main(){ int n,x; scanf("%d",&n); Heap H=Creatheap(n); for(int i=0;i<n;i++){ scanf("%d",&x); H=Insert(H,x); } n--; while(n--){ x=DeleteMin(H)+DeleteMin(H); ans+=x; //printf("%d\n",ans); H=Insert(H,x); //将最小两数之和,插入到堆中 } printf("%d",ans); }
标签:25,哈夫曼,int,牧场,木头,son,fa,Heap,Data 来源: https://www.cnblogs.com/ghostlx/p/13659940.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。