【算法通关指南:算法基础篇 】贪心专题之简单贪心:1.最大子段和 2.纪念品分组

【算法通关指南:算法基础篇 】贪心专题之简单贪心:1.最大子段和 2.纪念品分组
在这里插入图片描述
🔥小龙报:个人主页
🎬作者简介:C++研发,嵌入式,机器人方向学习者
❄️个人专栏:《算法通关指南》
永远相信美好的事情即将发生
在这里插入图片描述

文章目录

前言

本专栏聚焦算法题实战,系统讲解算法模块:以《c++编程》,《数据结构和算法》《基础算法》《算法实战》 等几个板块以题带点,讲解思路与代码实现,帮助大家快速提升代码能力ps:本章节题目分两部分,比较基础笔者只附上代码供大家参考,其他的笔者会附上自己的思考和讲解,希望和大家一起努力见证自己的算法成长

一、贪心

贪心算法是两极分化很严重的算法。简单的问题会让你觉得理所应当,难⼀点的问题会让你怀疑人生。在解决贪心问题我们有时不仅要理解贪心策略,也要学会证明贪心策略的正确性来提高思维的严密性。

1.1 什么是贪心算法

贪心算法也称作贪心策略:企图用局部最优找出全局最优
(1)把解决问题的过程分成若干步;
(2)解决每⼀步时,都选择"当前看起来最优的"解法;
(3)希望"得到全局的最优解

1.2 贪心算法的特点

总体特点:目光短浅
(1)对于绝大多数题目,贪心策略的提出并不是很难,难的是证明它是正确的。因为贪心算法相较于暴力枚举,每一步并不是把所有情况都考虑进去,而是只考虑当前看起来最优的情况。但是局部最优并不等于全局最优,所以我们必须要能严谨的证明我们的贪心策略是正确的。⼀般证明策略有:反证法,数学归纳法,交换论证法等等
(2)当问题的场景不同时,贪心的策略也会不同。因此,贪心策略的提出是没有固定的套路和模板的。

1.3 如何学习贪心?

(1)重点放在各种各样的策略上,把各种策略当成经验来吸收;
(2)在平常学习的时候,我们尽可能的证明⼀下这个贪心策略是否正确,这样有利于培养我们严谨的思维。# 二、简单贪心的经典算法题

二、简单贪心的经典算法题

2.1 最大子段和

2.1.1题目

链接:最大子段和

在这里插入图片描述

2.1.2 算法原理

贪心想法:从前往后累加,我们会遇到下面两种情况:
(1)目前的累加和 > 0 :那么当前累加和还会对后续的累加和做出贡献,那我们就继续向后累加,然后更新结果。
(2) 目前的累加和 < 0 :对后续的累加和做不了⼀点贡献,直接大胆舍弃计算过的这⼀段,把累加和重置为0,然后继续向后累加。
这样我们在扫描整个数组⼀遍之后,就能更新出最大子段和
:考虑到如果结果可能为负数所以可以在累加过程中一边更新结果不用做过多断判断。全为负数时既为求最大值。

2.1.3代码

#include <iostream>usingnamespacestd; typedef longlong LL;constint N =2e5+10; LL a[N];intmain(){int n; cin >> n;for(int i =1; i <= n; i++) cin >> a[i];LL sum =0;LL ret =-1e20;for(int i =1; i <= n; i++){ sum += a[i]; ret =max(ret, sum);if(sum <0) sum =0;} cout << ret << endl;return0;}

2.1.4 贪心策略证明

(1)证明方法:反证法
(2)证明思路:抓住向后加的时候,只要不小于0 ,就会⼀直加下的主线去在累加的过程中算出⼀段区间和sum[a,b] < 0,如果不舍弃这⼀段,那么 [a, b]段之间就会存在⼀点,「以某个位置为起点」就会「更优」,分为下面两种情况:

2.1.4.1证明过程:

(1)情况一:在ab段存在⼀个c点 ,从这个c位置开始,「不越过 」的累加和比从a开始的累加和更优:(元素全为负数不考虑,因为全为负数时该贪心策略本身就是正确的)

在这里插入图片描述


如果存在这⼀点,那么sum[c,k] > sum[a,k],但是如果sum[c,k] > sum[a,k],那么sum[a,c −1] < 0,这与我们的贪心策略矛盾既在区间加上元素b之前,区间中任意以a为左端点的一个子区间区间和都大于0。故该情况不成立的.
(2)情况二: 在ab段存在⼀个点c ,从这个位置开始,「越过b或者刚好在b」的累加和比从a开始的累加和更优:

在这里插入图片描述


如果存在这⼀点,那么:sum[c,b] > sum[a,b],但是如果sum[c,b] > sum[a,b],那么sum[a,c −1] < 0,与我们的贪心策略矛盾既在区间加上元素b之前,区间中任意以a为左端点的一个子区间区间和都大于0。故该情况不成立的.
故证毕

2.2 纪念品分组

2.2.1题目

链接:纪念品分组

在这里插入图片描述

2.2.2 算法原理

先将所有的纪念品排序,每次拿出当前的最小 值x与最大值y:
(1)如果把x+y ≤w:就把这两个放在⼀起;
(2)如果x+y >w:说明此时最大的和谁都凑不到⼀起, y单独分组, x继续留下在进行下⼀次判断。
直到所有的物品都按照上述规则分配之后,得到的组数就是最优解

2.2.3代码

#include <iostream>#include <algorithm>usingnamespacestd;constint N =3e4+10;int a[N];intmain(){int n,w; cin >> w >> n;for(int i =1; i <= n; i++) cin >> a[i];sort(a +1, a +1+ n);int l =1, r = n;int ret =0;while(l <= r)//相遇时给物品还未分配{if(a[l]+ a[r]<= w){ l++; r--;}else r--; ret++;} cout << ret << endl;return0;}

2.2.4 贪心策略证明

(1)证明方法:交换论证法
(2)证明思路:对于区间[ai…aj],如果存在最优解但是ai与aj的分配方式与我们贪心解的分配方式不一样,我们通过调整方式调整成贪心解

2.2.4.1证明过程:

(1) a[i] + a[j] > w时:
贪心解会把a[j]单独分组,a[i]留待下次考虑.
最优解也必定会把a[j]单独分组,因为没有更小的a[i]值与a[j]组合。此时贪心解与最优解一致。
(2)a[i] + a[j] ≤ w时:
贪心解会把两者组合分在一个组里面;最优解可能有以下几种情况
情况一:◦a[j]和a[k]和一组:
▪如果a[i]单独⼀组的话,a[j] + a[k]为一组,可以调整交换a[i]和a[k],此时并不影响结,与贪心解一致
▪如果a[i]和a[l]一组的话,交换a[l]和a[k],就会变成(a[i] + a[j]),(a[l] + a[k]),总体变成a[l] + a[k] ≤ a[j] + a[k] ≤ w,不影响最终结果,和贪心解⼀致
情况二:◦a[j]单独一组:
▪如果a[i]也单独⼀组的话,最优解还不如贪心解分的组少,矛盾。
▪如果a[i]和另⼀个a[k]组的话,我们可以把a[k]和a[j]交换,此时并不影响结,与贪心解一致
总之:综上所述,我们可以通过不断的「调整」,使的最优解在「不改变其最优性」的前提下,变得和贪心解一致。

总结与每日励志

✨本文介绍了贪心算法的基本概念、特点和学习方法,重点讲解了两道经典贪心算法题:最大子段和与纪念品分组。文章通过反证法和交换论证法严谨证明了贪心策略的正确性,并提供了相应的代码实现。贪心算法通过局部最优选择寻求全局最优解,虽然策略因问题而异,但掌握其证明方法能培养严密思维。作者鼓励读者保持积极心态,相信通过不断练习和思考能够提升算法能力。

在这里插入图片描述

Read more

别再瞎用 Git 合并了!Merge vs Rebase 底层逻辑、适用场景与零坑操作全指南

别再瞎用 Git 合并了!Merge vs Rebase 底层逻辑、适用场景与零坑操作全指南

几乎每个开发者每天都在和Git打交道,但分支合并时的灵魂拷问——“到底用Merge还是Rebase?”,却难倒了无数人。有人无脑用Merge,导致仓库提交历史分叉成“蜘蛛网”,回滚时无从下手;有人盲目跟风用Rebase,结果重写了公共分支历史,把整个团队的协作流程搞崩,甚至弄丢了线上代码。 这两个命令的核心区别到底是什么?什么时候该用哪个?怎么操作才能彻底避开坑?本文将从Git底层对象模型出发,用通俗的语言讲透Merge和Rebase的本质,搭配可直接复现的实战示例,明确区分易混淆点,给出企业级可落地的最佳实践,让你看完就能彻底搞懂,再也不会用错。 一、前置基础:Git分支的底层核心逻辑 要彻底搞懂Merge和Rebase,必须先理解Git的核心设计——Git是一个基于快照的分布式版本控制系统,分支本质是指向提交对象的可变指针。所有的合并操作,本质都是对提交对象和分支指针的操作。 1.1 Git提交对象的核心结构 Git中的每一次提交(commit),都是一个不可变的快照对象,包含4个核心信息,所有内容共同生成唯一的SHA-1哈希值: 1. tree对象:指向当前提交的文

By Ne0inhk
【Git#1】初识 git(配置 & 基本认识 & 文件操作)

【Git#1】初识 git(配置 & 基本认识 & 文件操作)

📃个人主页:island1314 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 * 生活总是不会一帆风顺,前进的道路也不会永远一马平川,如何面对挫折影响人生走向 – 《人民日报》 🔥 目录 * 一、前言 * 二、git 基本操作 * 1. 创建 Git 本地仓库 * 2. 配置 git * 三、认识工作区、暂存区、版本库 * 四、文件操作 * 1. 添加文件 -- 场景一 * 2. 了解 .git 下目录及文件 * 3. 添加文件 -- 场景二 * 4. 修改文件 * 5. 版本回退 * 6. 撤销修改 * 1️⃣对于工作区的代码,还没有

By Ne0inhk
英伟达开源DreamDojo:4.4万小时“梦境”,破解机器人数据鸿沟

英伟达开源DreamDojo:4.4万小时“梦境”,破解机器人数据鸿沟

摘要:本文深度解析英伟达开源的DreamDojo世界模型,详解DreamDojo的核心定位与开源战略,拆解44711小时超大规模数据集的优势、连续潜在动作的技术创新,剖析其实时遥操作、策略评估等应用场景,对比其与1XWM、Genie 3的技术路线差异,解读其与扬·勒丘恩物理AI理念的契合点,探讨DreamDojo对破解机器人物理鸿沟、推动物理AI发展的核心作用,为技术从业者、行业观察者、投资者提供最专业、最全面的深度解读,助力了解2026年世界模型与物理AI领域的最新技术革新与赛道趋势。 一、行业痛点:数据鸿沟,困住人形机器人的核心瓶颈 长期以来,“数据短缺+数据低效”是制约机器人行业发展的致命痛点——机器人想要掌握一项技能,需要海量真实场景下的动作数据进行训练,但真实数据的采集的成本极高、周期极长,且场景覆盖有限;与此同时,传统机器人数据集规模偏小、多样性不足,难以支撑通用型机器人的训练需求,形成了难以逾越的“数据鸿沟”。 更关键的是,多数企业陷入了“重指令、轻物理”的误区:大量布局视觉-语言-动作(VLA)模型,过度依赖文本推理驱动机器人动作,却忽略了直觉物理规律的核心价值。

By Ne0inhk
开源智能体搭建平台MaxKB4j 技术文档

开源智能体搭建平台MaxKB4j 技术文档

MaxKB4j 技术文档 项目概述 MaxKB4j (Max Knowledge Base for Java) 是一个基于 Java/Spring Boot 和 LangChain4j 构建的开源的 RAG(检索增强生成)知识库和 LLM 工作流平台,支持多模型集成、可视化工作流编排、知识库问答和多模态能力,专为构建企业级智能问答系统而设计。 核心特性 * 开箱即用的知识库问答: 支持上传本地文档或自动抓取网页内容,自动完成文本分块 → 向量化 → 向量数据库存储 → RAG 流程构建 * 模型无关的灵活集成: 支持多种主流大语言模型(OpenAI、Claude、Gemini、DeepSeek、Qwen、Ollama 等) * 可视化工作流编排: 内置低代码 AI 工作流引擎,支持条件分支、函数调用、多轮对话记忆 * MCP

By Ne0inhk