poj 3253 Fence Repair 贪心 最小堆 题解《挑战程序设计竞赛》

地址 http://poj.org/problem?id=3253

 

题解 

本题是<挑战程序设计>一书的例题

根据树中描述 所有切割的代价 可以形成一颗二叉树

而最后的代价总和是与子节点和深度相关的 由于切割的次数是确定的 该二叉树的节点就是确定的。

也就是说我们可以贪心的处理  最小长度的子节点放在最下面

如图

 

 

ac代码如下 使用了堆 记录每次最小的元素 

堆的使用真的不是很方便 , 另外还需要注意 爆int 所以需要使用long long 记录元素的和

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <vector>
 4 #include <assert.h>
 5 
 6 
 7 
 8 using namespace std;
 9 
10 /*
11 poj 3253
12 有一个农夫要把一个木板钜成几块给定长度的小木板,每次锯都要收取一定费用,这个费用就是当前锯的这个木版的长度
13 给定各个要求的小木板的长度,及小木板的个数n,求最小费用
14 提示:
15 16 3
17 8 8 5为例:
18 
19 先从无限长的木板上锯下长度为 21 的木板,花费 21
20 再从长度为21的木板上锯下长度为5的木板,花费5
21 再从长度为16的木板上锯下长度为8的木板,花费8
22 总花费 = 21 + 5 + 8 = 34
23 */
24 
25 
26 int main()
27 {
28     int n; long long ret = 0;
29     cin >> n;
30     vector<int> wood(n);
31     for (int i = 0; i < n; i++) {
32         cin >> wood[i];
33     }
34     make_heap(wood.begin(), wood.end(), greater<int>());
35 
36     while (wood.size() != 1) {
37         
38         pop_heap(wood.begin(), wood.end(), greater<int>());
39         long long total = wood.back();
40         wood.pop_back();
41 
42         pop_heap(wood.begin(), wood.end(), greater<int>());
43         total += wood.back();
44         wood.pop_back();
45 
46         ret += total;
47         wood.push_back(total);
48         push_heap(wood.begin(), wood.end(), greater<int>());
49     }
50 
51     cout << ret << endl;
52 
53     return 0;
54 }
View Code

 

 1 #include <iostream>
 2 #include <queue>
 3 
 4 #include <stdio.h>
 5 
 6 
 7 using namespace std;
 8 
 9 typedef long long LL;
10 
11 const int MAX_N = 100010;
12 int n, L[MAX_N];
13 
14 void solve()
15 {
16     LL ans = 0;
17     priority_queue<int, vector<int>, greater<int>> que;
18     for (int i = 0; i < n; i++) {
19         que.push(L[i]);
20     }
21 
22     while (que.size() > 1) {
23         int l1, l2;
24         l1 = que.top();
25         que.pop();
26         l2 = que.top();
27         que.pop();
28 
29         ans += l1 + l2;
30         que.push(l1 + l2);
31     }
32     printf("%lld\n", ans);
33 }
34 
35 
36 int main()
37 {
38     scanf("%d", &n);
39 
40     for (int i = 0; i < n; i++) {
41         scanf("%d", &L[i]);
42     }
43 
44     solve();
45 }
stl 堆

 

posted on 2019-12-06 17:11  itdef  阅读(294)  评论(0编辑  收藏  举报

导航