【算法】(Python)贪心算法

embedded/2024/12/12 6:41:13/

贪心算法

  • 又称贪婪算法,greedy algorithm。
  • 贪心地追求局部最优解,即每一步当前状态下最优选择。
  • 试图通过各局部最优解达到最终全局最优解。但不从整体最优上考虑,不一定全局最优解。
  • 步骤:从初始状态拆分成一步一步的,每一步确保当前状态最优解,再下一步。
  • 关键:具体的贪心策略(选择能产生问题最优解的最优度量标准)。
  • 使用条件:贪心选择(一个问题最优解可通过一系列局部最优解达到,每一步可依赖以前的选择,不可回溯),最优子结构(一个问题最优解包含其子问题的最优解)。

案例:

1、(难度:简单)【力扣】1710. 卡车上的最大单元数

 解题思路:每一步优先挑选当前可装载的最大单元数量的箱子。

  1. 将列表按单元数量(元素中下标为1的值)降序排列。
  2. 遍历列表中所有元素,
  3. 若当前元素的箱子最大数量已经达到指定总数量,则单元总数=指定总数量*单元数量,并结束,返回单元总数。
  4. 若当前箱子最大数量在指定总数量之内,则当前箱子最大数量*单元数量,累加到单元总数中,剩余指定总数量=指定总数量-当前箱子最大数量;
  5. 再判断列表中下一个元素,
  6. 直到遍历完列表中所有元素,或者达到指定总数量,返回单元总数。

 知识点:列表.sort(key=排序条件, reverse=True):列表按照排序条件降序排列。

class Solution:def maximumUnits(self, boxTypes: List[List[int]], truckSize: int) -> int:# 将列表按单元数量(即各元素下标为1的值)降序排列boxTypes.sort(key=lambda x: x[1], reverse=True)total = 0         # 记录可装载的单元总数# 遍历列表,指定最大数量依次减去最大箱子数量计算剩余数量,并统计单元总数# i为箱子数量,j为每个箱子的单元数量for i, j in boxTypes:if i >= truckSize:total += truckSize * jbreaktotal += i * jtruckSize -= ireturn total

2、(难度:中等)【力扣】714. 买卖股票的最佳时机含手续费

解题思路:买卖为一次交易、计算一次手续费,则买入时计算手续费。买入价尽可能当前最低价,卖出价尽可能当前最高价。

  1. 初始买入价为列表第一日价格(含手续费),
  2. 依次遍历列表中每日价格,
  3. 若当前价(含手续费)<买入价,即当前价格比前一天低,则当前价(含手续费)为新的买入价。若当前价(不含手续费)>买入价,则假装卖出,计算利润(若前一日也假装卖出则利润加上当前价与前一日的差价),并假装当天免手续费买入,即当天价(不含手续费)为买入价,
  4. 下一日价格,当前价再与买入价比较。
  5. 遍历完列表所有元素,返回总利润。
class Solution:def maxProfit(self, prices: List[int], fee: int) -> int:profit = 0                # 记录总收益buy = prices[0] + fee     # 初始买入# 遍历每个价格for i in prices:# 若当前价+手续费<买入价,则当前价买入if i + fee < buy:buy = i + fee# 当前价格>买入价,(假装卖出)计算利润(当前价与买入价的差),# 并假装以当前价免手续费买入(若明天价比当前价高,明天收益就是明天价与当前价之间的差)elif i > buy:profit += (i - buy)buy = ireturn profit

注:本题其他解题方法:动态规划。本文忽略。

3、(难度:困难)【力扣】871. 最低加油次数

解题思路:一个优先队列记录每个加油站的加油量(降序,最大油量在前)。计算每到一个地方的剩余油量,若不足则优先使用最大油量加油。

  1. 遍历每个地方和目的地(n+1),
  2. 计算从上一个位置到达当前地方后的剩余油量,
  3. 若剩余油量不足,则依次从优先队列取出最大油量加油,每加一次统计一次,直到加满或优先队列为空(即没有油可加),
  4. 若加完油后剩余油量仍不足,则无法到达目的地,返回-1,
  5. 每到达一个加油站,将加油量添加到优先队列,并将当前地方设为上一位置,用于下一个地方计算判断油量。

 知识点:二维数组[子数组下标][子数组中元素下标]:获取二维数组中元素。二维数组:数组中的元素类型仍为数组。

               python中heapq库用于操作堆(最小堆,最大堆),应用于优先队列和堆排序。此处为优先队列。

               heapq.heappush(队列, 元素):往优先队列添加元素,自动生成最小堆(父节点小于所有子节点,左右子节点无大小要求)。元素前加负号“-”,则各元素负数后的最小堆,类似最大堆,取出时前面也加负号“-”即为最大值。

               heapq.heappop(队列):从优先队列中取出最小值。

class Solution:def minRefuelStops(self, target: int, startFuel: int, stations: List[List[int]]) -> int:       import heapqres = 0               # 统计加油次数fuel_list = []        # 油量优先队列(最大的在前),记录每个加油站的加油量fuel = startFuel      # 记录目前油量pre = 0               # 记录上一个位置# 遍历每个加油站和目的地n = len(stations)for i in range(n + 1):# 记录当前位置,若加油站则为元素中下标为0的值,若目的地则为targetif i < n: cur = stations[i][0]else: cur = target# 计算达到当前位置,剩余油量fuel -= cur - pre# 若剩余油量<0,且油量优先队列中有元素,依次按最大油量加油,直到加满或油量优先队列为空while fuel < 0 and fuel_list:# 油量优先队列为了从大到小排列,元素是负数fuel += (-heapq.heappop(fuel_list))           # 从优先队列取出最大值res += 1# 若加油后,剩余油量仍<0,说明即使加满油也到不了目的地if fuel < 0: return -1# 每到一个加油站,将油量添加到油量优先队列中if i < n:# 油量优先队列为了从大到小排列,元素是负数heapq.heappush(fuel_list, -stations[i][1])    # 添加到优先队列(最大堆)pre = curreturn res

以上是从上次位置到达该加油站后剩余油量判断,也可以直接判断从起始位置到达各加油站时油量是否充足,若不足则取出油量优先队列的最大值加油。

class Solution:def minRefuelStops(self, target: int, startFuel: int, stations: List[List[int]]) -> int:import heapqh = []         # 油量优先队列(最大的在前),记录每个加油站的加油量res = 0        # 统计加油次数# 遍历每个加油站和目的地for long, fuel in stations + [[target, 0]]:# 若油量不够,则从优先队列取出最大油量加油while startFuel < long:# 若优先队列为空(即没有油可加),即无法到达目的地if not h: return -1startFuel -= heapq.heappop(h)res += 1# 每到一个加油站,就将油量添加到优先队列heapq.heappush(h, -fuel)return res

注:本题其他解题方法:动态规划。本文忽略。


http://www.ppmy.cn/embedded/135671.html

相关文章

nginx代理 proxy_pass

一 、代理后location不会被包含 location /master {proxy_pass http://127.0.0.1:81/api/master;} 请求地址&#xff1a; http://localhost/master/search 代理后的地址&#xff1a; http://127.0.0.1:81/api/master/search 二、代理后location会被包含 location /master …

动态规划 之 斐波那契数列模型 算法专题

动态规划 分析:(五步) 状态表示 状态表示是什么? dp表里面的值锁表示的含义 状态表示怎么来的? 题目要求经验 题目要求线性状态表经验: 以i位置为结尾 以i位置为起点分析问题的过程中, 发现重复子问题 状态转移方程 dp[i] 等于什么(一个公式) 用之前或者之后的状态, 推…

接口测试用例设计的关键步骤与技巧解析!

简介 接口测试在需求分析完成之后&#xff0c;即可设计对应的接口测试用例&#xff0c;然后根据用例进行接口测试。接口测试用例的设计也需要用到黑盒测试用例设计方法&#xff0c;和测试流程与理论章节的功能测试用例设计的方法类似&#xff0c;设计过程中还需要增加与接口特…

winform 加载 office excel 插入QRCode图片如何设定位置

需求&#xff1a;winform 加载 office excel 并加载QRCode图片&#xff0c;但是每台PC打印出来QRCode位置都不太一样&#xff0c;怎么办呢&#xff1f; 我的办法&#xff1a; 1、在sheet中插入一个 textbox &#xff0c;改名 qrcode &#xff08;这个名字随便设置&#xff09…

上海市计算机学会竞赛平台2022年8月月赛丙组搜索括号计分

题目描述 括号序列是由 ( 与 ) 构成的序列。平衡的括号序列要求 ( 与 ) 出现次数一样多&#xff0c;而且序列的每个前缀里 ( 出现次数不低于 ) 的出现次数。 对平衡的括号序列&#xff0c;定义一种计分规则如下&#xff1a; 如果只有一对括号 ()&#xff0c;只算 11 分&…

vue3 + ts + element-plus 二次封装 el-table

一、实现效果&#xff1a; &#xff08;1&#xff09;数据为空时&#xff1a; &#xff08;2&#xff09;有数据时&#xff1a;存在数据合并&#xff1b;可自定义表头和列的内容 &#xff08;3&#xff09;新增行&#xff1a; &#xff08;4&#xff09;删除行&#xff1a; &a…

2024年“数据要素×”大赛全国总决赛圆满收官!青海获农业赛道应用实践奖!

10月25日&#xff0c;2024年“数据要素”大赛全国总决赛颁奖仪式在北京顺利举行。青海省数据局按照国家数据局办赛要求&#xff0c;组织举办了“数据要素”大赛青海分赛&#xff0c;设置工业制造、现代农业、绿色低碳、文化旅游、科技创新、城市治理七大赛道&#xff0c;共有来…

超详细解读:《中国人工智能大模型技术白皮书》,看完你算是学完了半个大模型!

近期&#xff0c;中国人工智能协会发布了《中国人工智能大模型技术白皮书》&#xff0c;系统梳理了大模型技术演进&#xff0c;深入探讨关键技术要素&#xff0c;并剖析当前挑战及未来展望。我为大家做了简要总结&#xff0c;并附上原文供深入阅读。 目录 第 1 章 大模型技术…