POJ 3253 Fence Repair(贪心+优先队列)
2017-04-28 22:55
330 查看
原题地址
http://poj.org/problem?id=3253题意:农夫准备把总长度为L的木板切割成N块长度为L1,L2…LN的小木板,对于这N-1次切割,每次切割木板的费用为这块木板的长度。安排切割的次序,使得这N-1次切割的费用最少。
例如长度为21的木板要切成长度为5,8,8的三块木板。长度为21的木板切为长为13和8的木板时,费用为21;再将13切为5+8时,费用为13;总费用为21+13=34。
解题思路
这道题与之前做过的一道合并水果消耗最少体力值的题目很像,都是明显的贪心算法的应用,当然实现这里的贪心都是用huffman树。贴上书上给的思路:
学过哈夫曼编码的不难看出来这就是最优编码的问题。因此,每次都从板的集合里取出最短的两块板,将它们拼合后的长度之和加入集合中等待继续合并,不停重复直到合并为根节点(总长度)。
用最小堆+优先队列的数据结构实现非常方便,每次维护堆的复杂度为O(logN),一共要进行O(N)次维护堆,所以算法复杂度为O(NlogN)。
AC代码
#include <iostream> #include <algorithm> #include <queue> using namespace std; int main() { ios::sync_with_stdio(false); //优先队列实现最小堆 priority_queue<int, vector<int>, greater<int> > pq; int n, x; cin >> n; for (int i = 0; i<n; ++i) { cin >> x; pq.push(x); } long long ans = 0; //注意数据范围,可能会超出int导致WA int L1,L2; while (pq.size() > 1) //循环到只剩一块木板为止 { L1 = pq.top(); pq.pop(); //最短板 L2 = pq.top(); pq.pop(); //次短板 //合并木板并插入队列 ans += L1+L2; pq.push(L1+L2); } cout << ans << endl; return 0; }
算法复杂度:O(NlogN)
耗时:64ms
相关文章推荐
- POJ - 3253 Fence Repair ——贪心——优先队列
- poj 3253 Fence Repair(优先队列+贪心)
- poj 3253 Fence Repair (贪心+哈弗曼思想+优先队列)
- POJ 3253 Fence Repair (贪心&优先队列)
- 【POJ】3253 - Fence Repair(贪心 & 优先队列)
- POJ 3253 Fence Repair(贪心,优先队列)
- POJ 3253 Fence Repair(贪心+优先队列)
- POJ 3253 Fence Repair 贪心+优先队列
- POJ 3253 Fence Repair (割木头,贪心_优先队列)
- 贪心+优先队列(哈夫曼思想)POJ 3253 Fence Repair
- Poj 3253 Fence Repair【优先队列+贪心】
- poj 3253 Fence Repair(贪心+优先队列)
- POJ 3253 Fence Repair 霍夫曼树 贪心 优先队列
- POJ 3253 Fence Repair(贪心 + 优先队列)
- POJ 3253 Fence Repair(经典贪心问题)
- POJ 3253(贪心 + 优先队列)
- 【POJ】-3253-Fence Repair(优先队列)
- Fence Repair(优先队列) POJ 3253
- POJ 3253 Fence Repair(优先队列+思维贪心)(哈夫曼树算法)
- POJ 3253 贪心 优先队列