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

贪心算法学习四

例题一

解法(暴⼒解法 -> 贪⼼):
暴⼒解法:
a. 依次枚举所有的起点;
b. 从起点开始,模拟⼀遍加油的流程
贪⼼优化:
我们发现,当从 i 位置出发,⾛了 step 步之后,如果失败了。那么 [i, i + step] 这个区间内任意⼀个位置作为起点,都不可能环绕⼀圈。因此我们枚举的下⼀个起点,应该是 i + step + 1

例题二

解法(贪⼼):
假设我们有⼀个数 n,它有m位数字,每⼀位数字分别是 d1,d2,......,dm 我们想要修改这个数字,使得修改后的结果既⼩于原数字 n ,⼜满⾜单调递增和最⼤化。为了实现这个⽬标,我们需要将不满⾜递增的⾼位数字尽可能地减⼩。
⾸先,我们需要找到⼀个位置 k,使得 d 1 d 2 ≤...≤ d k > d k +1...(例如:12335412,k=4,d k=5)。这个位置 k 表⽰从⾼到低,第⼀个不满⾜单调递增的数字的位置。我们需要将这个数字减1,因为这是最⼩的减⼩量。
接下来,我们需要将低位数字都修改为9,这样可以保证修改后的数字是最⼤的,并且还能保证单调递增。修改后存在以下两种情况:
1. 如果d k −1 < dk ,则修改后的数字满⾜d 1 d 2 ≤ ... ≤ ( d k − 1) ≤ 9 ≤ ... ≤ 9 。这是因为 dk在减1的同时,低位数字被修改为 9。
2. 如果 d k −1 = dk,则修改后的数字满⾜ d 1 ≤ ... ≤ d k −1 > ( d k − 1) ≤ 9 ≤ ... ≤ 9。在这种情况下,我们仍然保证了低位数字的最⼤化和单调递增,但是可能会出现⾼位数字不再单调递增的情况。
第⼆种情况需要继续修改这个数字。我们需要找到⼀个位置 t ,使得d 1 d 2 ≤ ... < d t = d t +1 = ... = dk。这个位置 t 表⽰从⾼到低,最后⼀个⾼位数字相等的位置。我们需要将dt 减 1,并将之后的所有数字都修改为9,以满⾜d 1 d 2 ≤ ... ≤ d t − 1 ≤ 9 ≤ ... ≤ 9,即⾼位数字的单调递增和低位数字的最⼤化。
例如:1224444361,成功修改后的最⼤值为1223999999。
通过这种修改⽅式,我们可以得到⼀个新的数字,它既⼩于原数字 n,⼜满⾜单调递增和最⼤化。
算法思路:
1. 将整数 n 转换为字符串形式,以便于对其进⾏修改操作,并将其存储在字符串变量 str 中。
2. 初始化⼀个变量 pos,⽤于记录从⾼位到低位第⼀个不满⾜单调递增的数字的位置。初始值为 -1,表⽰在第⼀位之前。
3. 从⾼位到低位遍历字符串 str,寻找第⼀个不满⾜单调递增的数字的位置。当遇到⼀个数字⼩于前⼀个数字时,记录这个位置为 pos,并退出循环。
4. 如果 pos 被更新,说明存在需要修改的数字,执⾏以下操作:
a. 将 pos 位置后的所有数字修改为 9,这样可以保证修改后的数字是最⼤的。
b. 将 pos 位置的数字减⼀,因为这是最⼩的减少量,同时也能够保证修改后的数字仍然⼩于原数
字 n。
c. 检查 pos 前⼀位数字是否⼩于减⼀后的 pos 位置数字,如果⼩于,则说明在 pos 位置之前还有
相同的数字,需要将 pos 前⼀位数字减⼀,并将 pos 位置修改为 9。
i. 重复这个操作,直到 pos 前⼀位数字⼤于等于减⼀后的 pos 位置数字或 pos 已经移动到了第⼀位。
5. 将修改后的字符串 str 转换为整型数字并返回。

例题三

解法(贪⼼):
贪⼼策略:
正难则反:
当「反着」来思考的时候,我们发现:
i. end <= begin 的时候,只能执⾏「加法」操作;
ii. end > begin 的时候,对于「奇数」来说,只能执⾏「加法」操作;对于「偶数」来说,最好的⽅式就是执⾏「除法」操作这样的话,每次的操作都是「固定唯⼀」的。

例题四

解法(排序 + 贪⼼):
贪⼼策略:
a. 先按照区间的「左端点」排序:此时我们会发现,能够合并的区间都是连续的;
b. 然后从左往后,按照求「并集」的⽅式,合并区间。
如何求并集:
由于区间已经按照「左端点」排过序了,因此当两个区间「合并」的时候,合并后的区间:
a. 左端点就是「前⼀个区间」的左端点;
b. 右端点就是两者「右端点的最⼤值」。

例题五

解法(贪⼼):
贪⼼策略:
a. 按照「左端点」排序;
b. 当两个区间「重叠」的时候,为了能够「在移除某个区间后,保留更多的区间」,我们应该把 「区间范围较⼤」的区间移除。
如何移除区间范围较⼤的区间:由于已经按照「左端点」排序了,因此两个区间重叠的时候,我们应该移除「右端点较⼤」的区间.

例题六

解法(贪⼼):
贪⼼策略:
a. 按照左端点排序,我们发现,排序后有这样⼀个性质:「互相重叠的区间都是连续的」;
b. 这样,我们在射箭的时候,要发挥每⼀⽀箭「最⼤的作⽤」,应该把「互相重叠的区间」统⼀ 引爆。
如何求互相重叠区间?
由于我们是按照「左端点」排序的,因此对于两个区间,我们求的是它们的「交集」:
a. 左端点为两个区间左端点的「最⼤值」(但是左端点不会影响我们的合并结果,所以可以忽略);
b. 右端点为两个区间右端点的「最⼩值」。

相关文章:

  • 推荐常用的三款源代码防泄密软件
  • Cocos2d-x 4.0 工程首次建立与编译(Mac m1)
  • 利用C#和Snap7工具模拟S7通信(包含DB地址讲解)
  • B端业务需求分析的3大注意事项
  • 栈帧浅析,堆栈漏洞概述——【太原理工大学软件安全期末补充】
  • HarmonyOS开发日记 :自定义节点,实现 UI 组件 动态创建、更新
  • 279 基于matlab的粒子群集法对铁路电能质量控制系统的容量避行优化设计
  • 一文读懂OpenGVLab带来的最新视觉预训练框架
  • 【idea】解决springboot项目中遇到的问题
  • 智能网站管理系统
  • C语言运算中的临时匿名变量
  • JY-156/1静态电压继电器 板前接线 约瑟JOSEF
  • 人工智能中实现自动化决策与精细优化的核心驱动力
  • MySQL:概念、逻辑与物理结构设计详解
  • 【npm】console工具(含胶囊,表格,gif图片)
  • 【Amaple教程】5. 插件
  • 2017-08-04 前端日报
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • javascript面向对象之创建对象
  • JSDuck 与 AngularJS 融合技巧
  • Laravel 菜鸟晋级之路
  • Python学习笔记 字符串拼接
  • Quartz初级教程
  • SOFAMosn配置模型
  • Spark学习笔记之相关记录
  • Spring Cloud Feign的两种使用姿势
  • Unix命令
  • windows下mongoDB的环境配置
  • 创建一个Struts2项目maven 方式
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 说说动画卡顿的解决方案
  • 小程序测试方案初探
  • 由插件封装引出的一丢丢思考
  • 正则表达式
  • 7行Python代码的人脸识别
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 第二十章:异步和文件I/O.(二十三)
  • ​520就是要宠粉,你的心头书我买单
  • ​ArcGIS Pro 如何批量删除字段
  • ​configparser --- 配置文件解析器​
  • #HarmonyOS:基础语法
  • (1)(1.11) SiK Radio v2(一)
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (TOJ2804)Even? Odd?
  • (第61天)多租户架构(CDB/PDB)
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)Oracle存储过程编写经验和优化措施
  • (轉)JSON.stringify 语法实例讲解
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .NET Reactor简单使用教程
  • .net web项目 调用webService