贪心算法算法,完全零基础小白教程,不是计算机的都能学会!超详解

news2024/12/25 12:44:45

目录

一、基本概念

二、举几个例子,便于理解

1、找零问题

2、最小路径和

3、背包问题

1)只考虑体积的贪心策略:

2) 只考虑价值的贪心策略:

三、贪心策略的特点

四、贪心策略证明

四、如何学习贪心

五、例题分析

第一题

1、题目描述

2、贪心策略分析

3、代码

 第二题

1、题目描述

2、贪心策略分析

3、代码

 第三题

1、题目描述

2、贪心策略分析

3、代码

 第四题

1、题目描述

2、贪心策略分析

3、代码


一、基本概念

什么是贪心算法?
贪心算法不是一个具体的算法,而是一个策略。
具体的策略是:
1、把解决问题的过程氛围若干步
2、解决每一步,都选择当前看起来“最优”的解法
3、最后希望得到一个全局最优解。

二、举几个例子,便于理解

1、找零问题

你是一个超市前台,你有面额为【20,10,5,1】的零钱,数量不限
有个顾客来买东西,要找零50块。
你要给他找零,要求是给的钞票数最少。
按照贪心的策略,核心是我只考虑当前步数的最优的选法。
所以,按照贪心策略,我不管三七二十一,我不管后面怎么样子,我就只管当前的情况。
所以,50块,我先找两张最大的20
剩下10块,然后找一张10块。
结束。

2、最小路径和

以下有一个表格,

每一次只能向下或者向右走,现在要求从左上角走到右下角走的路径最小。
贪心法的策略就是:我不管三七二十一,那个小,我就走那个。我不管后面怎么样子,我就只管现在这一步。
因此:

3、背包问题


假设我们有以下几种物品,每种物品有价值和体积两个属性:
物品 A:价值 10,体积 2
物品 B:价值 8,体积 3
物品 C:价值 5,体积 4
物品 D:价值 3,体积 1
背包体积为8。现在要求尽可能的装东西,体积不超过8,要求价值最大化。

1)只考虑体积的贪心策略:


贪心的策略就是:我不管你别的,那个小,我选那个。
所以我直接选了8个D,3*8 -21;
但是实际上最佳的选择是4个A,价值为40.

2) 只考虑价值的贪心策略:


别的我不管,那个价值大我放那个。
所以按照价值从大到小的顺序选择物品放入背包。
选择4个价值最大的A,总价值为40.

三、贪心策略的特点

根据上述三个简单例子的理解,我们可以总结归纳贪心策略特点如下:
1、贪心策略没有标准和模板可以套用,需要具体问题具体分析
2、贪心策略所得结果无法保证最优解(因此,需要严格证明策略的正确性)

四、贪心策略证明

常用证明方法(数学方法):
1、贪心选择性质:证明贪心算法每一步的选择都是局部最优的,即当前情况下的最佳选择,不考虑未来可能发生的情况。
2、反证法:假设贪心算法得到的解不是最优解,然后推导出这个假设的结果与实际情况不符,从而证明贪心算法得到的解必须是最优的。
3、交换证明:通过比较贪心算法选择的解和任何其他算法选择的解,证明贪心算法的解比其他算法的解更优或者至少一样好。
4、拼接法:通过将贪心算法得到的局部最优解与其他算法得到的解拼接或组合,证明贪心算法整体上是最优的。

四、如何学习贪心?

根据以上内容,我们怎么学习贪心?
1、遇到不会做的贪心题目,非常正常,非常常见。
不会就去查,就去搜,就去模仿。
先积累模仿,再总结经验,慢慢积累,找感觉。
这就够了,不要想太多。
2、其次,慢慢的,要学会自己去证明贪心策略正确性的过程。

五、例题分析

第一题

1、题目描述

860. 柠檬水找零

  在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

2、贪心策略分析

5元不用找,10元找5元,20元找一张10和一张5,而不是3张5。每一次找零都尽可能的留下5,把10兑换出去。

3、代码

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int five = 0, ten = 0;
        for(auto e : bills)
        {
            if(e == 5)
            {
                five++;
            }
            else if(e == 10)
            {
                if(five == 0)
                {
                    return false;
                }
                else
                {
                    five--;
                    ten++;
                }
            }
            else //20
            {
                if(ten >= 1 && five >= 1)
                {
                    ten--;
                    five--;
                }
                else if(five >= 3)
                {
                    five -= 3;
                }
                else 
                {
                    return false;
                }
            }
            
        }
        return true;
    
    }
};

 第二题

1、题目描述

2208. 将数组和减半的最少操作次数 - 力扣(LeetCode)

给你一个正整数数组 nums 。每一次操作中,你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半。(注意,在后续操作中你可以对减半过的数继续执行操作)

请你返回将 nums 数组和 至少 减少一半的 最少 操作数。

2、贪心策略分析

每一次选择该数组中最大数字减半,可以使用一个堆,c++中对应的容器是优先队列,priority_queue。

3、代码

class Solution {
public:
    int halveArray(vector<int>& nums) {
        //用优先队列
        //每一次选取top出队列,减半,再插入队列
        //如此保证每一次选择得数据都是最大的
        std::priority_queue<double> q;
        double sum = 0;
        for(auto e : nums)
        {
            sum += e;
            q.push(e);
        }
        double count = 0;
        double half = sum / 2;
        double ret = sum ;

        while(!q.empty())
        {
            double top = q.top() / 2;
            q.pop();
            q.push(top);
            ret -= top;
            count++;
            
            if(ret <= half)
            {
                break;
            }
            
        }
        return count;
    }
};

 第三题

1、题目描述

179. 最大数 - 力扣(LeetCode)

2、贪心策略分析

本题的本质是确定元素的先后顺序
但是,排序规则不同于以往的大小,而是以结果大小为标准。
因此,贪心策略:每一次选择,选择两个数字进行组合,看a和b组合,是ab大还是ba大。

lambda表达式:
[](参数列表){返回值}

3、代码

class Solution {
public:
    string largestNumber(vector<int>& nums) {
        //转换成字符串
        vector<string> v;
        for(auto x : nums)
        {
            v.push_back(to_string(x));
        }
        
            //按照规则排序
            //在范围内进行排序,同时使用lambad表达式
            sort(v.begin(),v.end(),[](const string& s1, const string& s2)
            {
                return s1 + s2 > s2 + s1;
            });
        

        string ret;
        for(auto& e : v)
        {
            ret += e;
        }

        if(ret[0] == '0')
        {
            return "0";
        }

        return ret;
    }
};

 第四题

1、题目描述

376. 摆动序列 - 力扣(LeetCode)

2、贪心策略分析

贪心策略:
当升序时,选择升序序列最大的,保证后面有更多的降序数字满足摆动
当降序时,选择降序序列最小的,保证后面有更多的升序数字满足摆动
即,波峰和波谷。

怎么判断该数字是不是波峰/波谷?
设置状态
设置一个数字的左边和右边
如果left*right<0
说明,要么是波峰,要么是波谷。

3、代码

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size() < 2)
            return 1;

        int ret = 0;
        int left = 0;

        for(int i = 0; i < nums.size() - 1; i++)
        {
            int right = nums[i+1] - nums[i];
            if(right == 0)//非波峰/谷
                continue;

            if(left * right <= 0)//该点是一个波峰/波谷
                ret++;

            left = right;
        }

            return ret + 1;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1887565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity海面效果——4、法线贴图和高光

Unity引擎制作海面效果 大家好&#xff0c;我是阿赵。 继续做海面效果&#xff0c;上次做完了漫反射颜色和水波动画&#xff0c;这次来做法线和高光效果。 一、 高光的计算 之前介绍过高光的光照模型做法&#xff0c;比较常用的是Blinn-Phong 所以我这里也稍微连线实现了一下 …

问题-小技巧-Win11的常用快捷方式和有用快捷方式

文章目录 常用快捷方式1、CtrlA 全部选中2、Ctrl Z 撤销3、Ctrl X 剪切4、Ctrl C 粘贴5、Ctrl V 复制6、winshifts截图&#xff0c;Windows系统自带截图工具&#xff0c;功能太少7、ctrlshifts截图&#xff0c;edge自带截图工具&#xff0c;使用时需要打开edge8、 winv 可以查看…

实习总结 --- 内部平台使用

常用术语 CR CR–标准问题分类管理平台&#xff1a;由业务类型-角色-国家-品类-Page定义。 FAQSOP FAQ是端上用户自助的第一道关口&#xff0c;在引导用户进行自助解决上起关键作用 SOP是指标准作业程序&#xff0c;客服SOP是针对用户遇到的具体问题场景&#xff0c;给客服…

编写静态库

一、静态库 1.制作完成整体目录结构 2.首先创建mymath.c和mymath.h 3.编写Makefile 4.创建测试的main函数 test文件夹 先把lib移到test文件夹里面 4.编译链接 gcc main.c -I ./lib/include/ -L ./lib/mymathlib/ -l mymath 5.形成可执行程序a.out 要是不想执行第四步那么麻烦…

揭秘软件性能测试方法和注意事项,专业软件测试公司分享

目前&#xff0c;随着云计算和大数据的发展&#xff0c;软件的性能需求越来越高&#xff0c;用户对于软件的性能体验也有了更高的期望。因此&#xff0c;进行软件性能测试不仅是一种需求&#xff0c;更是一种责任&#xff0c;是开发过程中必不可少的一环。软件性能测试&#xf…

Python容器 之 元组

1.元组的介绍 1, 元组 tuple, 使用的是 () 2, 元组和列表非常相似, 都可以存储多个数据, 都可以存储任意类型的数据 3, 区别就是 元组中的数据不能修改,列表中可以修改 4, 因为元组中的数据不能修改,所以只能 查询方法, 如 index, count ,支持下标和切片 5, 元组, 主要用于…

ArcTs布局入门03——层叠布局(Stack)

如果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01; 扫描下面的二维码关注公众号。 1、概述 叠布局&#xff08;StackLayout&#xff09;用于在屏幕上预留一块区域来显示组件中的元素&#xff0c;提供元素可以重叠的布局。层叠布局通过Stack容器组件实…

【鸿蒙学习笔记】基础组件 Button

官方文档&#xff1a;按钮 (Button)添加链接描述 官方文档&#xff1a;button开发指导 目录标题 属性迭代完善不含子组件的按钮包含子组件的按钮ButtonType添加事件跳转超链接提交表单悬浮按钮 属性迭代完善 不含子组件的按钮 Column({ space: 10 }) {Row() {Button(添加子目…

全国总工会党组书记徐留平来苏调研 观摩体验苏州金龙无人驾驶巴士

6月28日&#xff0c;全国总工会党组书记、副主席、书记处第一书记徐留平率队来苏州调研工会工作&#xff0c;并在苏州市劳模工匠人才创新成果展上观摩体验苏州金龙无人驾驶巴士。 本届苏州市劳模工匠人才创新成果展共设20个展位&#xff0c;集中展示了全市“劳模工匠助企行”的…

java面试-SpringAOP

1.SpringAOP的使用 你了解Spring AOP 吗&#xff1f; 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 2.SpringAOP的原理 我们可以将ASM生成的类进行缓存&#xff0c;这样能解决生成的类比较低效的问题。 ASM是可以操作字节码的框架。 真实实现类和…

数据库操作语言(DML)

数据库操作语言&#xff08;DML&#xff09; 文章目录 数据库操作语言&#xff08;DML&#xff09;一、四种操作二、数据的插入&#xff08;增&#xff09;三、数据的删除&#xff08;删&#xff09;四、数据的修改&#xff08;改&#xff09;五、数据的查询&#xff08;查&…

RK3568驱动指南|第十五篇 I2C-第179章在应用程序中使用I2C

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

WPDRRC信息安全体系架构模型

构建信息安全保障体系框架应包括技术体系、组织机构体系和管理体系等三部分&#xff0c;也就是说&#xff1a;人、管理和技术手段是信息安全架构设计的三大要素&#xff0c;而构成动态的信息与网络安全保障体系框架是实现系统的安全保障。 1.WPDRRC信息安全模型的定义 WPDRRC…

Oracle - 数据库打补丁实践

原文&#xff1a;https://www.cnblogs.com/ddzj01/p/12097467.html 一、概述 本文将介绍如何给oracle数据库打最新补丁&#xff0c;数据库版本为11.2.0.4单实例&#xff0c;操作系统为redhat6.5 二、下载相关升级包 1. 登录MOS&#xff0c;查阅(ID 2118136.2)&#xff0c;下载…

电脑录音方法:电脑怎么录音?5招轻松搞定录音!

想要从麦克风或系统音频录制电脑声音吗&#xff1f;这是一项简单的任务。本文将为您介绍5种最佳且最简单的方法&#xff0c;包括使用Windows系统自带的录音工具来录制电脑音频&#xff0c;在线音频录音软件和专业的第三方电脑录音软件。这些工具都能够很好地帮助您完成电脑怎么…

MySQL数据库中文乱码处理

出现中文乱码之后处理方式 1、执行下面语句查看一下关于编码方式 show variables like %char%结果展示&#xff1a;【你应该和我的不一样】 2、如果你的和我查询结果不一致请设置成一致语句&#xff0c;根据自己需要复制语句 如下&#xff1a;【除了最后一条记录哈】 SET G…

llm-universe | 五. 系统评估与优化

系统评估与优化 一.LLM应用评估思路1.人工评估准则一 量化评估准则二 多维评估 2.自动评估方法一. 构造客观题方法二. 计算答案相似度 3.使用大模型评估4.混合评估 二.评估并优化生成部分1. 提升直观回答质量2.标明知识来源&#xff0c;提高可信度3. 构造思维链4.增加一个指令解…

独立开发者系列(10)——fastadmin后台框架的认识

软件开发项目涉及到的东西非常多&#xff0c;作为独立开发者&#xff0c;普遍性的面对的是中小项目。而其中接单的情况下&#xff0c;以WEB方向的居多。其中主要有以下这么些类的:搭建官网cms 就是常见的资讯发布平台&#xff0c;发布一些企业新闻/活动宣传&#xff0c;纯粹是…

Docker部署ETCD 3.5.14(保姆级图文教程)

系列文章目录 Docker部署Nginx 1.21.5&#xff08;保姆级图文教程&#xff09; Docker部署MySQL 8.3.0&#xff08;保姆级图文教程&#xff09; Docker部署ETCD 3.5.14&#xff08;保姆级图文教程&#xff09; 文章目录 一、环境二、拉取镜像2.1 查找 Docker Hub 上的 ETCD 镜像…

【区块链+基础设施】国家健康医疗大数据科创平台 | FISCO BCOS应用案例

在医疗领域&#xff0c;疾病数据合法合规共享是亟待解决的难题。一方面&#xff0c;当一家医院对患者实施治疗后&#xff0c;若患者转到其 他医院就医&#xff0c;该医院就无法判断诊疗手段是否有效。另一方面&#xff0c;医疗数据属于个人敏感数据&#xff0c;一旦被泄露或被恶…