2014-05-03 21:57
原题:
Many sticks with length, every time combine two, the cost is the sum of two sticks' length. Finally, it will become a stick, what's the minimum cost?
题目:有很多根长度不同的棍子,每次选择其中两根拼起来,每次拼接的代价为两木棍长度之和。问把所有棍子拼成一根最少需要花多大代价。
解法:描述这么麻烦,还不如直接问哈夫曼编码呢。根据贪婪原则,每次选取长度最短的两个木棍即可。用小顶堆可以持续进行这个过程,直到只剩一根木棍为止。由于单个堆操作是对数级的,所以算法总体复杂度是O(n * log(n)),空间复杂度为O(n)。仿函数greater和less,对应于小顶堆和大顶堆。起初我经常搞反,时间长了就记住了。
代码:
1 // http://www.careercup.com/question?id=4557716425015296 2 #include <queue> 3 #include <vector> 4 using namespace std; 5 6 template <class T> 7 struct greater { 8 bool operator () (const T &x, const T &y) { 9 return x > y; 10 }; 11 }; 12 13 class Solution { 14 public: 15 int minimalLengthSum(vector<int> &sticks) { 16 int i, n; 17 int sum; 18 int num1, num2; 19 20 sum = 0; 21 n = (int)sticks.size(); 22 for (i = 0; i < n; ++i) { 23 pq.push(sticks[i]); 24 } 25 26 for (i = 0; i < n - 1; ++i) { 27 num1 = pq.top(); 28 pq.pop(); 29 num2 = pq.top(); 30 pq.pop(); 31 sum += num1 + num2; 32 pq.push(num1 + num2); 33 } 34 35 while (!pq.empty()) { 36 pq.pop(); 37 } 38 39 return sum; 40 }; 41 private: 42 // min heap 43 priority_queue<int, vector<int>, greater<int> > pq; 44 };