最優二叉樹的思想可以應用在很多方面,下面就是一個例子:
/*
Description
“What an amazing garden!” Tiantian exclaimed. When she walks in the garden, she finds that fruit falls and automatically forms a line! “Maybe you can be superwoman after eating all the fruit” Tiantian said to herself. So an idea came to her! She would like
to pile the fruit together and move them away. But as a girl, it’s so hard for her to move more than one pile once, so she would like to merge two piles of fruit together once a time. And to make the work smoothly, she wants to do it with the least cost, can
you help her?
Each pile of fruit has a weight. If there are two piles of fruit, their weights are a and b,then merging this two piles of fruit together will cost a+b, and the weight of the new fruit pile is a+b.
Input
The input contains several test cases. Each test case starts with a line containing an integer N (1<=N<=10000), which describes the number of the piles of fruit in the garden. And then N integers follow in the next line, separated by a space, to describe
the N weight of the N piles of fruit. All of them is an integer no larger than 20000.
Output
For each test case, output only one line of an integer, to tell the least cost for Tiantian to pay. It’s sure that the result will be no more than 2147483647.
Sample Input
3
1 2 9
Sample Output
15
Hint
First, Tiantian piles the first two piles of fruit together, and cost 1+2=3, and they form a new pile of fruit weights 3. Then Tiantian piles the left two piles of fruit together, and cost 3+9=12. So the total cost is 3+12=15.
*/
題目的意思很明顯,就是有一堆數字,先取出最小的兩個數,相加組成一個新的數加到原來的數組中,依次類推,直到只剩下一個數,就是我們要求的值。
這就符合了最優二叉樹的思想:先取兩個權值最小的節點,構造出的父節點加到其他節點中去,依次類推,實現構造一棵樹。只要把所有節點的權值相加,就是我們所要的結果。
這裡面唯一一個問題是一個數組如何取最小值,如果用遍曆的方法,取出所有的數的時間複雜度無疑是O(n^n)。我是使用優先隊列的方法,這樣就把時間複雜度降低到o(nlgn),沒什麼難度,代碼如下:
#include<iostream>#include<fstream>#include<string>#include<vector>#include<queue>using namespace std;struct cmp{bool operator()(int x,int y){return (x>y);}};int main(){int n;while(cin>>n){int total=0;priority_queue<int,vector<int>,cmp> data;for(int i=0;i<n;i++){int tmp;cin>>tmp;data.push(tmp);}//end of n//判斷只有一個元素的時候if(data.size()==1){cout<<data.top()<<endl;continue;}//用優先隊列取出最小的兩個while(!data.empty()){int tmp1,tmp2;tmp1=data.top();data.pop();tmp2=data.top();data.pop();total+=tmp1+tmp2;if(!data.empty())data.push(tmp1+tmp2);}//end of whilecout<<total<<endl;}//end or while}