题目链接:
http://poj.org/problem?id=3253
题目大意:
有一根木棍,需要截成n节,每节都有固定的长度,一根长度为x的木棒结成两段,需要花费为x,问截成需要的状态需要最小的花费?
解题思路:
哈夫曼数,把每节需要的木棒长度看做树上的节点,把截木棍的过程倒过来,变成把n截木棍接起来,这两个过程的花费是一样的。根据哈夫曼的性质,可知先把最短的两个木棍连起来后,放到剩下的n-2根木棍中,再选取两个最短的连接起来,再放回去,直到全部的木根都连在一起就ok了。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <queue> 8 using namespace std; 9 10 int main () 11 { 12 priority_queue <int> Q;//优先队列,默认大的先出队,所以我们把进队的数取负 13 int n; 14 long long sum, num, m; 15 scanf ("%d", &n); 16 while (n --) 17 { 18 scanf ("%d", &m); 19 Q.push(-m);//进队 20 } 21 sum = 0; 22 while (Q.size() > 1)//队列里面的元素个数要大于1 23 { 24 num = 0; 25 26 num += Q.top();//出队两个最短木棍 27 Q.pop(); 28 29 num += Q.top(); 30 Q.pop(); 31 32 sum += num;//连接起来 33 Q.push(num);//进队 34 } 35 printf ("%lld ", -sum); 36 return 0; 37 }