poj 3253 Fence Repair (水哈夫曼树)

题目链接:

  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\n", -sum);
36     return 0;
37 }

 

posted @ 2015-04-29 14:20  罗茜  阅读(171)  评论(0编辑  收藏  举报