欢迎来到Cefler的博客😁
🕌博客主页:那个传说中的man的主页
🏠个人专栏:题目解析
🌎推荐文章:题目大解析(3)
前言
1.什么是贪心算法?——贪婪+鼠目寸光
贪心策略:解决问题的策略,局部最优->全局最优
(1)即把解决问题的过程分为若干步
(2)解决每一步的时候吗,都选择当前看起来“最优的”解法
(3)希望得到全局最优解
2.贪心算法的特点
(1) 贪心策略的提出是没有标准以及模板的
(2) 可能每一道题的贪心策略都是不同的
(3)贪心策略的正确性:可能会出错;正确的贪心策略,我们是需要“证明的”
3.证明贪心策略的方法:数学中见过的所有证明方法
4.学习贪心的方向
(1):遇到不会的贪心题,很正常,把心态放平
(2):把策略当成经验吸收
(3):能证明则证明贪心策略的正确性
目录
- 👉🏻柠檬水找零
- 证明
- 👉🏻将数组和减半的最少操作次数
- 证明
- priority_queue
- 注意事项
👉🏻柠檬水找零
原题链接:柠檬水找零
mycode:
class Solution {
public:bool lemonadeChange(vector<int>& bills) {int five = 0,ten = 0,twenty = 0;for(auto e:bills){if(e==5){five++;}else if(e==10){ten++;if(--five<0)return false;}else if(e==20){twenty++;//10+5 && 5+5+5 都不可以才找零失败int tmp1 = ten,tmp2 = five,tmp3 = five;if(--tmp1>=0&&--tmp2>=0){--ten;--five;}else if((tmp3-=3)>=0){five-=3;}elsereturn false;}}return true;}
};
证明
交换论证法:
👉🏻将数组和减半的最少操作次数
原题链接:将数组和减半的最少操作次数
mycode:
class Solution {
public:int halveArray(vector<int>& nums) {priority_queue<double> heap;//默认大堆double sum = 0.0;for(auto e:nums){heap.push(e);sum+=e;}sum/=2.0;int count = 0;while(sum>0){double t = heap.top()/2.0;heap.pop();sum-=t;count++;heap.push(t);}return count;}
};
证明
priority_queue
当涉及到按照特定顺序处理元素时,C++ 的 std::priority_queue
是一个非常有用的容器适配器。它是一个基于堆的数据结构,用于实现优先级队列。在优先级队列中,元素按照其优先级被处理,具有较高优先级的元素先被处理。
以下是 std::priority_queue
的基本特征和用法:
包含头文件
#include <queue>
创建优先级队列
std::priority_queue<int> pq; // 创建一个默认的最大堆
插入元素
pq.push(10);
pq.push(5);
pq.push(20);
访问顶部元素
int topElement = pq.top(); // 获取最高优先级的元素,但不删除
删除顶部元素
pq.pop(); // 删除最高优先级的元素
自定义比较函数
如果你想要自定义元素的比较方式,可以通过提供自定义比较函数来实现。以下是一个示例,创建一个最小堆:
#include <functional>std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
或者,你也可以自定义比较函数:
struct Compare {bool operator()(int a, int b) {// 自定义比较逻辑,返回 true 表示 a 的优先级高于 breturn a > b;}
};std::priority_queue<int, std::vector<int>, Compare> customQueue;
注意事项
- 默认情况下,
std::priority_queue
是一个最大堆,但你可以通过提供第三个参数(比较函数)来改变其行为。 std::priority_queue
不提供迭代器访问元素的方式,因为堆不是线性结构。- 在使用自定义比较函数时,确保比较函数是严格弱序(strict weak ordering),以确保正确的行为。