POJ 3253 Fence Repair STL 优先队列

这题做完后觉得很水,主要的想法就是逆过程思考,原题是截断,可以想成是拼装,一共有n根木棍,最后要拼成一根完整的,每两根小的拼成一根大的,拼成后的木棍长度就是费用,要求费用最少。显然的是一共会拼接n-1次,如果把每根木棍最初的长度想成叶子节点,两个节点的父节点就是这两个节点的长度相加。那么求的就是这n-1个父节点的总和最少。

为实现这个目标,我们使每个父节点的值尽可能的少,由此想到哈夫曼编码的原理。初始条件为一共n根木棍。然后从中选出最短的两根,将这两根拼接成一根,这样得到的父节点的值是最小的。然后将这根木棍放进原来的木棍中,重复该步骤(从木棍堆中选出最短的两根,拼接成一根,放回木棍堆中),进行了n-1次操作后,木棍拼接成了一根完整的,把中间凡是被拼接成的木棍的长度累加起来,即为所求。

其实我并不能证明这种想法一定是正确的,只是感觉很对,结果也AC,我就当它是对的吧。。。

下面是代码,主要用了STL 中的优先队列,push(),pop(),top()函数。

优先队列默认是int型时最大值出来,所以这里要这样定义

   priority_queue< int,vector<int>,greater<int> > Q;

这样就是int型时最小值出来。

贴代码:

 1 #include <cstdio>
 2 #include <queue>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int n;
 8     scanf("%d",&n);
 9     priority_queue< int,vector<int>,greater<int> > Q;
10     for(int i=0; i<n; ++i)
11     {
12         int t;
13         scanf("%d",&t);
14         Q.push(t);
15     }
16     long long int ans =0;
17     for(int i=1;i<n;++i)
18     {
19         int c1,c2;
20         c1 = Q.top();
21         Q.pop();
22         c2 = Q.top();
23         Q.pop();
24         c1 += c2;
25         Q.push(c1);
26         ans += c1;
27     }
28     printf("%I64d
",ans);
29     return 0;
30 }
View Code
原文地址:https://www.cnblogs.com/allh123/p/3225977.html