当前位置: 首页 > news >正文

剖析算法内部结构----------贪心算法

什么是贪心算法?

贪心算法(Greedy Algorithm)是一种在问题求解过程中,每一步都采取当前状态下最优(即最有利)的选择,从而希望导致最终的全局最优解的算法策略。
贪心算法的核心思想是做选择时,每一步只考虑当前情况的最佳选择,不考虑整体情况,也不考虑这个选择将如何影响未来的选择。
下面是贪心算法的一些基本特点:

  1. 局部最优选择:在每一步选择中都采取当前状态下最优的选择。
  2. 不可回溯:一旦做出了选择,就不可撤销,也就是选择了某一部分的解之后,就不再考虑这个选择之前的其他可能性。
  3. 最优子结构:问题的最优解包含其子问题的最优解,子问题的最优解能被合并为问题的最优解。
    贪心算法适用于具有“最优子结构”和“贪心选择性质”的问题。
    以下是一些可以用贪心算法解决的问题的例子:
  • 找零问题:给出一个金额,如何用最少数量的硬币找零。
  • 哈夫曼编码:用于数据压缩的最优前缀编码方法。
  • 图的最小生成树:例如普里姆算法(Prim’s Algorithm)和克鲁斯卡尔算法(Kruskal’s Algorithm)。
  • 图的最短路径问题:迪杰斯特拉算法(Dijkstra’s Algorithm)在某些条件下可以看作是贪心算法。

贪心算法的步骤通常如下:
4. 初始化:根据问题设定,选择一个初始解作为当前解。
5. 选择:根据某种贪心标准,从候选集合中选出最优解的一个元素,并将它添加到当前解中。
6. 更新:根据上一步的选择,更新候选集合,排除不再可行的选项。
7. 循环:重复“选择”和“更新”步骤,直到达到问题的解。
贪心算法并不总是能得到最优解,它只有在问题具有贪心选择性质时才有效。对于一些问题,贪心算法可以得到最优解,而对于其他问题,贪心算法可能只能得到近似最优解。
贪心算法虽然简单高效,但在某些问题上可能无法得到最优解。以下是贪心算法的一些局限性:
8. 不能保证全局最优解:贪心算法在选择每一步的局部最优解时,可能不会导致全局最优解。这是因为贪心算法没有从整体的角度考虑问题,而是基于当前情况做出选择。
9. 不可回溯:贪心算法一旦做出选择,就不会撤销这个选择,即使这个选择后来被证明是错误的。这种不可回溯的特性意味着贪心算法可能无法纠正之前的错误选择。
10. 不适用于所有问题:贪心算法只适用于具有“贪心选择性质”和“最优子结构”的问题。如果一个问题不满足这些特性,贪心算法就不能保证找到最优解。

在这里插入图片描述

谈心算法的局限性

以下是贪心算法局限性的具体例子:

  • 组合问题:在组合问题中,选择一个元素可能会影响其他元素的选择。贪心算法可能无法处理这种相互依赖的情况。
  • 需要考虑所有可能组合的问题:对于需要考虑所有可能组合的问题,贪心算法可能无法工作,因为它只考虑当前的最优选择,而不是所有可能的组合。
  • 动态规划问题:对于需要考虑过去选择对未来决策影响的问题,贪心算法通常不是最佳选择。动态规划算法更适合这类问题,因为它考虑了所有可能的选择。
    以下是贪心算法局限性的具体表现:
  • 不能处理具有重叠子问题的情况:贪心算法通常不适用于具有重叠子问题的问题,因为它不会存储子问题的解以供后续使用。
  • 可能需要额外的数据结构来支持:在某些情况下,贪心算法可能需要额外的数据结构(如优先队列)来有效地选择下一个最优元素,这可能会增加算法的复杂度。
  • 局部最优解可能不构成全局最优解:在某些问题中,局部最优解的集合并不一定能够组合成全局最优解。
  • 难以证明最优性:对于某些问题,证明贪心算法的最优性可能非常困难,甚至是不可能的。
    因此,在使用贪心算法时,需要仔细分析问题是否适合贪心策略,以及是否存在更有效的算法(如动态规划、回溯算法等)来解决问题。

在这里插入图片描述

贪心算法和动态规划的区别是什么?

贪心算法和动态规划是两种不同的算法设计技术,它们在解决问题的方式上有显著的区别。以下是它们之间的一些主要区别:

  1. 问题解决策略
    • 贪心算法:在每一步选择中都采取当前状态下最优的选择,即局部最优解,不考虑这一选择将如何影响未来的选择。
    • 动态规划:将复杂问题分解为多个子问题,每个子问题只解决一次,并将子问题的解存储起来以供后续使用,从而避免重复计算。
  2. 最优子结构
    • 贪心算法:通常假设通过局部最优选择可以构造出全局最优解,但这并不总是成立。
    • 动态规划:明确利用问题的最优子结构性质,即问题的最优解包含其子问题的最优解。
  3. 决策过程
    • 贪心算法:做出决策后通常不可回溯,一旦选择了某个选项,就会一直使用这个选项。
    • 动态规划:考虑所有可能的决策,并选择导致最优解的决策路径。
  4. 适用范围
    • 贪心算法:适用于具有贪心选择性质的问题,即局部最优选择能导致全局最优解。
    • 动态规划:适用于具有重叠子问题和最优子结构性质的问题。
  5. 算法复杂度
    • 贪心算法:通常实现简单,运行效率高,但可能无法保证找到最优解。
    • 动态规划:可能需要更多的计算和存储空间,因为它需要存储所有子问题的解,但可以保证找到最优解。
  6. 正确性证明
    • 贪心算法:证明其正确性通常比较困难,需要证明局部最优解能组合成全局最优解。
    • 动态规划:正确性通常基于数学归纳法,通过证明最优解包含子问题最优解来证明。
  7. 例子
    • 贪心算法:找零问题、哈夫曼编码、图的最小生成树(如克鲁斯卡尔算法)。
    • 动态规划:背包问题、最长公共子序列、最短路径问题(如贝尔曼-福特算法)。
      总结来说,贪心算法是一种简化版的动态规划,它在每一步都做出最优选择,而不考虑这个选择对未来决策的影响。动态规划则考虑所有可能的决策,并通过子问题的最优解来构造全局最优解。贪心算法在某些问题上可能非常高效,但它不一定能找到最优解,而动态规划则可以保证在适用的问题上找到最优解。

在这里插入图片描述

贪心算法上楼梯

"贪心算法上楼梯"这个问题通常可以这样描述:假设你正在上楼梯,每次可以向上走1步、2步或3步,问到达楼梯顶部有多少种不同的走法。
这个问题实际上并不适合直接用贪心算法来解决,因为贪心算法在选择每一步时只考虑当前最优的选择,而不考虑未来的影响。在这个楼梯问题中,贪心选择并不一定能得到最优解,因为可能需要根据剩余楼梯的步数来调整每一步的选择。
不过,如果我们假设每一步都可以选择走1步、2步或3步,并且我们希望用最少的步数到达楼梯顶部,那么我们可以尝试用贪心算法的思想来解决这个问题。以下是使用贪心算法解决这个问题的步骤:

  1. 初始化:确定楼梯的总步数n
  2. 贪心选择:在每一步尽可能多地走,优先选择3步,然后是2步,最后是1步。
  3. 计算步数:根据楼梯的总步数n,计算每一步选择的次数。
    下面是一个简单的实现:
#include <stdio.h>
// 使用贪心算法计算上楼梯的最少步数
void greedyStairs(int n) {int steps = 0; // 总步数int threeSteps = 0; // 走3步的次数int twoSteps = 0; // 走2步的次数int oneStep = 0; // 走1步的次数// 首先尽可能多地走3步threeSteps = n / 3;n -= threeSteps * 3;// 然后尽可能多地走2步twoSteps = n / 2;n -= twoSteps * 2;// 最后走剩下的1步oneStep = n;// 输出结果printf("走3步的次数: %d\n", threeSteps);printf("走2步的次数: %d\n", twoSteps);printf("走1步的次数: %d\n", oneStep);printf("总步数: %d\n", threeSteps + twoSteps + oneStep);
}
int main() {int n;printf("请输入楼梯的总步数: ");scanf("%d", &n);greedyStairs(n);return 0;
}

请注意,这个贪心算法的实现仅仅计算了到达楼梯顶部所需的最少步数,并没有计算出所有可能的走法。实际上,要计算所有可能的走法,通常需要使用动态规划或递归算法。

贪心算法找零

在这里插入图片描述

贪心算法的一个经典例子是找零问题。在这个问题中,你有一个收银机,里面有一定数量的硬币,比如1元、5元、10元、20元和50元。当顾客需要找零时,你的目标是使用最少数量的硬币来凑成所需找零的金额。
以下是使用贪心算法解决找零问题的步骤:

  1. 初始化:确定需要找零的金额。
  2. 贪心选择:在每一步,选择面值最大的硬币,只要它不超过还需要找零的金额。
  3. 更新剩余金额:从需要找零的金额中减去所选硬币的面值。
  4. 重复:重复步骤2和步骤3,直到剩余找零金额为0。
    下面是找零问题的一个简单实现:
#include <stdio.h>
// 硬币面值的数组,按从大到小的顺序排列
int coins[] = {50, 20, 10, 5, 1};
int numCoins = sizeof(coins) / sizeof(coins[0]);
// 使用贪心算法计算找零所需的最少硬币数量
void greedyChange(int amount) {int coinCount = 0; // 硬币总数for (int i = 0; i < numCoins; i++) {// 选择当前最大的硬币,只要它不超过剩余金额int coin = coins[i];int count = amount / coin; // 可以使用该硬币的数量coinCount += count;amount -= count * coin; // 更新剩余金额printf("使用面值%d元的硬币%d个\n", coin, count);}printf("总共需要%d个硬币\n", coinCount);
}
int main() {int amount;printf("请输入需要找零的金额: ");scanf("%d", &amount);greedyChange(amount);return 0;
}

在这个例子中,贪心算法能够给出最优解,因为我们假设硬币的面值是标准的,并且找零问题具有贪心选择性质,即每次选择最大面值的硬币不会影响后续选择的最优性。
贪心算法的其他例子包括:

  • 哈夫曼编码:用于数据压缩的最优前缀编码方法。
  • 图的最小生成树:例如普里姆算法(Prim’s Algorithm)和克鲁斯卡尔算法(Kruskal’s Algorithm)。
  • 图的最短路径问题:迪杰斯特拉算法(Dijkstra’s Algorithm)在某些条件下可以看作是贪心算法。
    这些例子展示了贪心算法在不同问题领域的应用,尽管在某些情况下需要额外的条件来保证贪心算法能够得到最优解。
    在这里插入图片描述

相关文章:

剖析算法内部结构----------贪心算法

什么是贪心算法&#xff1f; 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在问题求解过程中&#xff0c;每一步都采取当前状态下最优&#xff08;即最有利&#xff09;的选择&#xff0c;从而希望导致最终的全局最优解的算法策略。 贪心算法的核心思想是做选择时&…...

uni-app开发微信小程序注意事项,不要用element-ui

前端扩展组件千万不要用element-ui&#xff0c;开发的时候不报错&#xff0c;发布的时候会报错无法发布。 可以用vant weapp【注意是weapp】 iView weapp 附上hbuilder官方文档 组件的概念 | uni-app官网 (dcloud.net.cn)...

Hibernate的检索策略(lazy、fetch、batch-size)

Hibernate的检索策略包括立即检索和延迟检索&#xff0c;可以在配置文件中通过对lazy、fetch、batch-size属性的设置来进行控制。一对多、多对多、多对一和一对一关系下的不同检索策略将影响对数据库访问的效率。 检索策略 立即检索&#xff0c;立即加载检索方法指定的对象延…...

算法训练(leetcode)第四十六天 | 110. 字符串接龙、105. 有向图的完全可达性、106. 岛屿的周长

刷题记录 *110. 字符串接龙105. 有向图的完全可达性邻接矩阵邻接表 106. 岛屿的周长深搜简化代码 *110. 字符串接龙 题目地址 使用广搜。 本题相当于求最短路径&#xff0c;因此使用广搜。如何应用广搜是一个难点&#xff0c;因为题目给的是字符串而非图的表示&#xff08;邻…...

自定义Mybatis-Plus分布式ID生成器(解决ID长度超过JavaScript整数安全范围问题)

自定义MyBatis-Plus分布式ID生成器&#xff08;解决ID长度超过JavaScript整数安全范围问题&#xff09; 版本 MyBatis-Plus 3.4.1 问题 MyBatis-Plus 默认生成的是 64bit 长整型&#xff0c;而 JS 的 Number 类型精度最高只有 53bit&#xff0c;如果以 Long 类型 ID 和前端…...

2024剪辑神器盘点:四大热门剪辑软件推荐!

亲爱的朋友们&#xff0c;想要制作出精彩短视频&#xff0c;却苦于找不到合适的剪辑工具&#xff1f;别担心&#xff0c;今天要向大家推荐几款剪辑软件&#xff0c;它们能帮助大家更好地完成视频创作&#xff01; 福昕视频剪辑 链接&#xff1a;www.pdf365.cn/foxit-clip/ 对…...

sql注入靶场sqli-labs常见sql注入漏洞详解

目录 sqli-labs-less1 1.less1普通解法 1.在url里面填写不同的值&#xff0c;返回的内容也不同&#xff0c;证明&#xff0c;数值是进入数据库进行比对了的&#xff08;可以被注入&#xff09; 2.判断最终执行的sql语句的后面还有内容吗&#xff0c;并且能够判断是字符型的拼接…...

[C++] 模板进阶:特化与编译链接全解析

文章目录 非类型模板类型形参非类型模板参数代码示例 **模板的特化**为什么要有模板的特化函数模板特化使用场景与示例函数模板特化的实现细节 类模板特化全特化示例 偏特化部分优化通过进一步限制模板参数进行特化偏特化为指针类型示例&#xff1a;偏特化为引用类型示例&#…...

oracle-备份

1、逻辑备份&#xff08;exp) /ljbb/oracle/o19c/bin/exp hr/hr tablesJOBS file/ljbb/bak/system.sql log/ljbb/bak/ststem.log query\where deptno30\ buffer100000000 hr/hr 用户/密码 tablesJOBS 表名&#xff1a;JOBS file/ljbb/bak/system.sql 备份文件路径 log/ljbb/ba…...

oracle 并行parallel的插入insert用法

在Oracle数据库中&#xff0c;INSERT 语句确实可以使用 Parallel&#xff08;并行&#xff09;功能。通过并行插入&#xff0c;可以在插入数据时同时利用多个并行操作进程来执行插入操作&#xff0c;从而显著提高插入操作的速度和效率。这对于需要处理大量数据插入的场景尤为有…...

夜莺监控使用指南

夜莺监控使用指南 本文用于解决在部署和应用夜莺监控中遇到的一些问题以及官方文档缺失的某些步骤可能会遇到的坑。 安装过程 我使用是NightingaleCategrafPrometheus的架构。 Nightingale安装文档&#xff1a;https://flashcat.cloud/docs/content/flashcat-monitor/night…...

MySQLDM笔记-查询库中是否存在列出的表名及查询库中列出的不存在的表名

如下表名&#xff1a; aaa,bb,cc,ccs,dds,csdf,csdfs,sdfa,werwe,csdfsd 在MySQL库中&#xff0c;查询哪些表名在数据库中 SELECT table_name FROM information_schema.tables WHERE table_schema your_database_name_here AND table_name IN (aaa, bb, cc, ccs, dds, csdf…...

第9天 xxl-job

使用xxl-job需要建表 引入依赖 添加配置 Bean public XxlJobSpringExecutor xxlJobExecutor() {logger.info(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor new XxlJobSpringExecutor();xxlJo…...

C++字符串<string>库

一&#xff1a;string及其标准库 C中使用string类需要添加<string>库。 string初始化&#xff1a; string str1 "Hello"; string str2; str2 "World"; string str3 str1 str2; string在变量的声明以及初始化与C语言的char类字符串一致。但是str…...

智能分析,安全无忧:AI视频分析技术在安全生产中的深度应用

在当今快速发展的科技时代&#xff0c;视频智能分析技术&#xff08;Intelligent Video Analysis&#xff0c;简称IV&#xff09;已经成为提升安全生产水平的重要手段。这一技术通过计算机图像视觉分析技术&#xff0c;实现了对场景中目标的自动识别和追踪&#xff0c;有效提升…...

02 Canal的安装使用

1 下载Canal Cannal下载地址如下&#xff1a;https://github.com/alibaba/canal/releases,这里选择Canal 1.1.4版本下载。2 上传解压 #首先创建目录 “/software/canal” [rootnode3 ~]# mkdir -p /software/canal#将Canal安装包解压到创建的canal目录中 [rootnode3 ~]# tar …...

【网络安全】玲珑安全第四期

鉴于玲珑安全漏洞挖掘前三期课程取得的优异成绩和获得的强烈反响,我们决定启动玲珑安全第四期漏洞挖掘培训计划。 文章目录 往期学员收获基础学员报喜(部分)课程反馈第四期课程课程内容免费课程往期学员收获 第一期课程总结及学员收获:->点我查看第一期学员收获<- …...

【工具】图片背景移除界面 UI 源码

移除图片背景的UI 照片背景移除和填充颜色的用户界面 仓库地址&#xff1a;https://github.com/MengWoods/remove-background-ui/tree/main 介绍 该项目提供了一个基于 removebg 库的用户界面&#xff0c;用于从输入的照片中移除背景&#xff0c;并用不同的颜色填充背景。 …...

CentOS linux 安装openssl(openssl拒绝服务漏洞【CVE-2022-0778】解决)

一、安装 1.下载相关openssl包 下载地址&#xff1a; https://www.openssl.org/source/ 2.将下载好的压缩包放到 /app/server/nginx 路径下&#xff08;根据自己实际需求定义&#xff09; 3.切换至该路径 cd /app/server/nginx4.压缩包解压 压缩包解压 &#xff1a;tar -…...

假如有一个嵌套集合,怎么通过stream流将集合放到一个集合之中?

假如有一个嵌套集合&#xff0c;怎么通过stream流将集合放到一个集合之中&#xff1f; 问题解释&#xff1a;你有一个嵌套的集合&#xff0c;想要通过 Stream 流的方式将其中嵌套的集合放到一个新的集合中。可以使用 flatMap 方法来实现。这种方法非常适合处理嵌套集合的情况。…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法

使用 ROS1-Noetic 和 mavros v1.20.1&#xff0c; 携带经纬度海拔的话题主要有三个&#xff1a; /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码&#xff0c;来分析他们的发布过程。发现前两个话题都对应了同一…...