STL 最大堆与最小堆

  在第一场CCCC选拔赛上,有一关于系统调度的水题。利用优先队列很容易AC。

  // 由于比赛时花费了不少时间研究如何定义priority_queue的比较函数,决心把STL熟练掌握...

  

Queue

  首先来看http://www.cplusplus.com/reference/queue/queue/对STL Queue容器的介绍。

  在C++中只要#include<queue>可使用队列类,常用的成员函数有

1. push

2. pop

3. size

4. empty

5. front

6. back     // 目前还没使用过,留意一下

  队列在BFS时经常使用,已经比较熟悉其用法。

 

Priority_queue

  在CPP网站上同样也有优先队列的详细介绍。在《数据结构与算法分析》一书上,堆(heap)等同于优先队列,或者准确地说,优先队列是通过堆实现的。

  相比队列,priority_queue的成员函数名基本一致,除了将front改为top,都是获取队首元素。

1. push

2. pop

3. size

4. empty

5. top

priority_queue<int, vector<int>, greater<int> > q;  // 小顶堆  
priority_queue<int, vector<int>, less<int> > q;     // 大顶堆,默认  

// 自定义数据结构
// 方式一
struct Node{  
    int x, y;  
    Node(int a = 0, int b= 0):x(a), y(b) {}  
};  
   
struct cmp{  
    bool operator() (const Node& a, const Node& b ){  
        if (a.x == b.x)   
            return a.y > b.y;  
        return a.x > b.x;   
    }  
};  

priority_queue<Node, vector<Node>, cmp> q;

// 方式二
struct Node{  
    int x, y;  
    Node(int a = 0, int b= 0):x(a), y(b) {}  
};  
  
bool operator < (const Node& a, const Node& b ){  
    if (a.x == b.x)   
        return a.y > b.y;  
    return a.x > b.x;   
}  

   上次比赛时,我忘了如何加上vector<int>部分,摸索半天通过方式二(编写的友元函数实现)才成功调试好代码,浪费了大量的时间。希望以后能记牢,平常多加练习达到熟练运用的水平^_^

 

STL 堆操作

  // 参考COPY自https://blog.csdn.net/my_lovely_lemon_tree/article/details/78007316 

  头文件是#include <algorithm>
  一般用到这四个:make_heap()、pop_heap()、push_heap()、sort_heap();
  (1)make_heap()构造堆
  void make_heap(first_pointer,end_pointer,compare_function);
  默认比较函数是(<),即最大堆。
  函数的作用是将[begin,end)内的元素处理成堆的结构

  (2)push_heap()添加元素到堆
  void push_heap(first_pointer,end_pointer,compare_function);
  新添加一个元素在末尾,然后重新调整堆序。该算法必须是在一个已经满足堆序的条件下。
  先在vector的末尾添加元素,再调用push_heap

  (3)pop_heap()从堆中移出元素
  void pop_heap(first_pointer,end_pointer,compare_function);
  把堆顶元素取出来,放到了数组或者是vector的末尾。
  要取走,则可以使用底部容器(vector)提供的pop_back()函数。
  先调用pop_heap再从vector中pop_back元素

  (4)sort_heap()对整个堆排序
  排序之后的元素就不再是一个合法的堆了。


 

转载于:https://www.cnblogs.com/izcat/p/10505388.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答你的问题。 首先,0-1背包问题是一个经典的背包问题,其目标是在限定的背包容量下,选择一些物品使得它们的总价值最大。但是,每个物品只能选择一次,即要么放入背包中,要么不放。这个问题可以使用分支限界算法来解决。 分支限界算法是一种搜索算法,它通过维护一个优先级队列来存储待搜索的解状态空间节点。每次搜索时,从队列中取出优先级最高的节点进行扩展,直到找到最优解或者队列为空。 具体实现时,我们可以定义一个节点类,其中包含以下成员变量: - 当前背包容量 - 当前价值 - 剩余物品 - 已选择的物品序列 然后,我们可以使用C++ STL中的最小堆来实现优先级队列。具体来说,我们可以定义一个比较函数,根据节点的价值和剩余物品数量来比较节点的优先级,然后将节点插入到最小堆中。每次取出堆顶节点进行扩展,直到找到最优解或者堆为空。 以下是伪代码实现: ```c++ #include <iostream> #include <queue> #include <vector> using namespace std; class Node { public: int capacity; // 当前背包容量 int value; // 当前价值 vector<int> remaining; // 剩余物品 vector<int> selected; // 已选择的物品序列 }; struct CompareNode { bool operator()(const Node& node1, const Node& node2) const { return node1.value + node1.remaining.size() > node2.value + node2.remaining.size(); } }; int knapsack(int capacity, vector<int>& weights, vector<int>& values) { priority_queue<Node, vector<Node>, CompareNode> pq; Node init; init.capacity = capacity; init.value = 0; init.remaining = vector<int>(weights.begin(), weights.end()); init.selected = vector<int>(weights.size(), 0); pq.push(init); int max_value = 0; while (!pq.empty()) { Node node = pq.top(); pq.pop(); if (node.remaining.empty()) { max_value = max(max_value, node.value); continue; } int weight = node.remaining.back(); node.remaining.pop_back(); if (node.capacity >= weight) { Node next1 = node; next1.capacity -= weight; next1.value += values[values.size() - node.remaining.size() - 1]; next1.selected[values.size() - node.remaining.size() - 1] = 1; pq.push(next1); } Node next2 = node; next2.selected[values.size() - node.remaining.size() - 1] = 0; pq.push(next2); } return max_value; } ``` 在这个实现中,我们使用了一个辅助函数knapsack来计算0-1背包问题的最大价值。在这个函数中,我们首先将初始节点插入到优先级队列中,然后循环取出队列中的节点进行扩展。如果节点的剩余物品为空,则更新最大价值并跳过循环。否则,我们取出剩余物品中的最后一个物品,并分别考虑将它放入背包中和不放入背包中两种情况。如果能够放入背包中,则创建一个新节点并插入到优先级队列中。如果不能放入背包中,则直接创建一个新节点并插入到优先级队列中。 最后,我们可以调用这个函数来解决0-1背包问题,例如: ```c++ int main() { vector<int> weights = { 2, 2, 4, 5, 3 }; vector<int> values = { 2, 3, 1, 4, 2 }; int capacity = 10; int max_value = knapsack(capacity, weights, values); cout << "Maximum value: " << max_value << endl; return 0; } ``` 这个程序将输出最大价值为10,即选择物品2、3、5。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值