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

目录

一、基本概念

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

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;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

eNSP中WLAN的配置和使用

一、基础配置 1.拓扑图 2.VLAN和IP配置 a.R1 <Huawei>system-view [Huawei]sysname R1 GigabitEthernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 200.200.200.200 24 b.S1 <Huawei>system-view [Huawei]sysname S1 [S1]vlan 100 [S1-vlan100]vlan 1…

IAR工程目录移动报错(改变文件目录结构)

刚开始用IAR&#xff0c;记录一下。 工作中使用华大单片机&#xff0c;例程的文件目录结构太复杂了想精简一点。 1.如果原本的C文件相对工程文件&#xff08;.eww文件&#xff09;路径变化了&#xff0c;需要先打开工程&#xff0c;再将所有的.c文件右键Add添加进工程&#xf…

PHP7源码结构

PHP7程序的执行过程 1.PHP代码经过词法分析转换为有意义的Token&#xff1b; 2.Token经过语法分析生成AST&#xff08;Abstract Synstract Syntax Tree&#xff0c;抽象语法树&#xff09;&#xff1b; 3.AST生成对应的opcode&#xff0c;被虚拟机执行。 源码结构&#xff1…

昇思25天学习打卡营第14天|CycleGAN图像风格迁移互换

模型介绍 模型简介 CycleGAN(Cycle Generative Adversarial Network) 即循环对抗生成网络&#xff0c;该模型实现了一种在没有配对示例的情况下学习将图像从源域 X 转换到目标域 Y 的方法。 该模型一个重要应用领域是域迁移&#xff0c;它只需要两种域的数据&#xff0c;而不…

2023-2024华为ICT大赛中国区 实践赛网络赛道 全国总决赛 理论部分真题

Part1 数通模块(10题)&#xff1a; 1、如图所示&#xff0c;某园区部署了IPv6进行业务测试&#xff0c;该网络中有4台路由器&#xff0c;运行OSPFv3实现网络的互联互通&#xff0c;以下关于该OSPFv3网络产生的LSA的描述&#xff0c;错误的是哪一项?(单选题) A.R1的LSDB中将存在…

Java高级重点知识点-13-数据结构、List集合、List集合的子类

文章目录 数据结构List集合List的子类&#xff08;ArrayList集、LinkedList集&#xff09; 数据结构 栈 stack,又称堆栈&#xff0c;它是运算受限的线性表&#xff0c;其限制是仅允许在标的一端进行插入和删除操作&#xff0c;不允许在其他任何位置进行添加、查找、删除等操作…

如何下载huggingface仓库里某一个文件

如何下载huggingface仓库里某一个文件&#xff1a; https://huggingface.co/PixArt-alpha/PixArt-Sigma/tree/main 直接用命令&#xff1a; wget https://huggingface.co/PixArt-alpha/PixArt-Sigma/resolve/main/PixArt-Sigma-XL-2-2K-MS.pth

30个!2024重大科学问题、工程技术难题和产业技术问题发布

【SciencePub学术】中国科协自2018年开始&#xff0c;组织开展重大科技问题难题征集发布活动&#xff0c;引导广大科技工作者紧跟世界科技发展大势&#xff0c;聚焦国家重大需求&#xff0c;开展原创性、引领性研究&#xff0c;不断夯实高质量发展的科技支撑。 自2024年征集活动…

南京林业大学点云相关团队论文

【1】Chen Dong, Wan Lincheng, Hu Fan, Li Jing, Chen Yanming, Shen Yueqian*, Peethambaran Jiju, 2024. Semantic-aware room-level indoor modeling from point clouds, International Journal of Applied Earth Observation and Geoinformation, 2024, 127, 103685. 语义…

QT5 static_cast实现显示类型转换

QT5 static_cast实现显示类型转换&#xff0c;解决信号重载情况

一款十六进制编辑器,你的瑞士军刀!!【送源码】

软件介绍 ImHex是一款功能强大的十六进制编辑器&#xff0c;专为逆向工程师、程序员以及夜间工作的用户设计。它不仅提供了基础的二进制数据编辑功能&#xff0c;还集成了一系列高级特性&#xff0c;使其成为分析和修改二进制文件的理想工具。 功能特点 专为逆向工程、编程和夜…

【AI】Image Inpainting

学习参考摘抄来自&#xff1a;大模型修复徐克经典武侠片&#xff0c;「全损画质」变4K&#xff0c;还原林青霞40年前绝世美貌 火山引擎多媒体实验室 &#xff08;1&#xff09;清晰度 去噪、去压缩、去模糊、超分辨率、人像增强 &#xff08;2&#xff09;流畅度 智能插帧算…

3.js - 纹理的重复、偏移、修改中心点、旋转

你瞅啥 上字母 // ts-nocheck // 引入three.js import * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js // 导入twee…

补浏览器环境

一&#xff0c;导言 // global是node中的关键字&#xff08;全局变量&#xff09;&#xff0c;在node中调用其中的元素时&#xff0c;可以直接引用&#xff0c;不用加global前缀&#xff0c;和浏览器中的window类似&#xff1b;在浏览器中可能会使用window前缀&#xff1a;win…

Latex写作工具整理(Overleaf)

一、公式&#xff08;MathType&#xff09; 先用MathType编辑好公式&#xff0c;再粘贴到Overleaf 预置-剪切和复制预置-选择“MathML或Tex"-确定 1.行内公式 粘贴到overleaf里面把两侧的" \["替换成"$" $ A $ 2.单行公式 \begin{equation}\labe…

Mysql并发控制和日志

文章目录 一、并发控制锁机制事务&#xff08;transactions&#xff09;事务隔离级别 二、日志事务日志错误日志通用日志慢查询日志二进制日志 备份在线查看二进制离线查看二进制日志 一、并发控制 锁机制 锁类型&#xff1a; 读锁&#xff1a;共享锁&#xff0c;也称为 S 锁…

方法种类的详解

1.有参无返回值 会出现在什么场景呢&#xff1f;比如我现在需要得到两个数&#xff08;哪里调用&#xff0c;哪里就给我&#xff09;&#xff0c;求和打印或者是打印三个数之和。 语法&#xff1a; 定义的语法&#xff1a; 修饰符 返回类型 方法名&#xff08;形参数1类型 …

[22] Opencv_CUDA应用之 使用背景相减法进行对象跟踪

Opencv_CUDA应用之 使用背景相减法进行对象跟踪 背景相减法是在一系列视频帧中将前景对象从背景中分离出来的过程&#xff0c;它广泛应用于对象检测和跟踪应用中去除背景 背景相减法分四步进行&#xff1a;图像预处理 -> 背景建模 -> 检测前景 -> 数据验证 预处理去除…

【Excel操作】Python Pandas判断Excel单元格中数值是否为空

判断Excel单元格中数值是为空&#xff0c;主要有下面两种方法&#xff1a; 1. pandas.isnull 2. pandas.isna判断Excel不为空&#xff0c;也有下面两种方法&#xff1a; 1. pandas.notna 2. pandas.notnull假设有这样一张Excel的表格 我们来识别出为空的单元格 import panda…

C#的五大设计原则-solid原则

什么是C#的五大设计原则&#xff0c;我们用人话来解释一下&#xff0c;希望小伙伴们能学会&#xff1a; 好的&#xff0c;让我们以一种幽默的方式来解释C#的五大设计原则&#xff08;SOLID&#xff09;&#xff1a; 单一职责原则&#xff08;Single Responsibility Principle…