修理牧场(哈夫曼树 )
?
農夫要修理牧場的一段柵欄,他測量了柵欄,發現需要N塊木頭,每塊木頭長度為整數L?i??個長度單位,于是他購買了一條很長的、能鋸成N塊的木頭,即該木頭的長度是L?i??的總和。
但是農夫自己沒有鋸子,請人鋸木的酬金跟這段木頭的長度成正比。為簡單起見,不妨就設酬金等于所鋸木頭的長度。例如,要將長度為20的木頭鋸成長度為8、7和5的三段,第一次鋸木頭花費20,將木頭鋸成12和8;第二次鋸木頭花費12,將長度為12的木頭鋸成7和5,總花費為32。如果第一次將木頭鋸成15和5,則第二次鋸木頭花費15,總花費為35(大于32)。
請編寫程序幫助農夫計算將木頭鋸成N塊的最少花費。
輸入格式:
輸入首先給出正整數N(≤10?4??),表示要將木頭鋸成N塊。第二行給出N個正整數(≤50),表示每段木塊的長度。
輸出格式:
輸出一個整數,即將木頭鋸成N塊的最少花費。
輸入樣例:
8 4 5 1 2 1 3 1 1輸出樣例:
49?題解:在百度百科上了解到了哈夫曼樹的定義:
結點的帶權路徑長度為從該結點到樹根之間的路徑長度與結點上權的乘積。樹的帶權路徑長度為樹中所有葉子結點的帶權路徑長度之和,通常記作WPL。
若有n個權值為w1,w2,...,wn的結點構成一棵有n個葉子結點的二叉樹,則樹的帶權路徑最小的二叉樹叫做哈夫曼樹或最優二叉樹。
而這題的模型剛好是哈夫曼樹,然后我們可以利用優先隊列來做這道題:
代碼:
#include<cstdio> #include<cstring> #include<cstring> #include<iostream> #include<queue>using namespace std;int main() {int n;priority_queue<int ,vector<int>,greater<int> >q;cin>>n;int m,sum=0;for(int t=0;t<n;t++){scanf("%d",&m);q.push(m);}int x1,x2;while(q.size()>1){x1=q.top();q.pop();x2=q.top();q.pop();sum+=x1+x2;q.push(x1+x2);}cout<<sum<<endl;return 0; }?
轉載于:https://www.cnblogs.com/Staceyacm/p/10782062.html
總結
以上是生活随笔為你收集整理的修理牧场(哈夫曼树 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Delphi与各数据库数据类型比较
- 下一篇: Eclipse中Maven项目出现红色感