贪心算法精解:用C++征服最优解问题
贪心算法精解:用C++征服最优解问题
一、贪心算法的本质:当下最优即全局最优

贪心算法如同下棋高手,每一步都选择当前最优的走法。它的核心思想是:通过局部最优选择的叠加,最终得到全局最优解。这种算法在时间复杂度上往往具有显著优势,但需要严格满足两个条件:
- 贪心选择性质:每一步的局部最优解能导致全局最优解
- 最优子结构:问题的最优解包含子问题的最优解
二、五大经典应用场景与C++实现
2.1 活动选择问题
#include <vector>
#include <algorithm>
using namespace std;struct Activity { int start, end; };vector<Activity> selectActivities(vector<Activity> activities) {sort(activities.begin(), activities.end(), [](const Activity& a, const Activity& b){ return a.end < b.end; });vector<Activity> result;int lastEnd = 0;for (auto& act : activities) {if (act.start >= lastEnd) {result.push_back(act);lastEnd = act.end;}}return result;
}// 示例输入:{{1,3}, {2,5}, {3,7}, {0,1}, {5,9}}
// 输出结果:{0-1, 1-3, 3-7, 5-9}
2.2 霍夫曼编码
#include <queue>struct Node {char data;int freq;Node *left, *right;Node(char d, int f) : data(d), freq(f), left(nullptr), right(nullptr) {}
};struct Compare {bool operator()(Node* a, Node* b) {return a->freq > b->freq;}
};Node* buildHuffmanTree(const vector<pair<char, int>>& freq) {priority_queue<Node*, vector<Node*>, Compare> pq;for (auto& p : freq) pq.push(new Node(p.first, p.second));while (pq.size() > 1) {Node* left = pq.top(); pq.pop();Node* right = pq.top(); pq.pop();Node* merge = new Node('$', left->freq + right->freq);merge->left = left; merge->right = right;pq.push(merge);}return pq.top();
}
三、贪心VS动态规划:选择策略大对决
| 对比维度 | 贪心算法 | 动态规划 |
|---|---|---|
| 时间复杂度 | O(n log n) 典型 | O(n^2) 常见 |
| 空间复杂度 | O(1) 常额外空间 | O(n) 表存储 |
| 最优解保证 | 需严格验证条件 | 总能得到最优解 |
| 适用场景 | 局部最优=全局最优 | 重叠子问题最优结构 |
| 经典问题 | 最小生成树、Dijkstra | 背包问题、LCS |
四、贪心算法的三大陷阱与规避策略
4.1 硬币找零的经典反例
vector<int> greedyCoins(int amount) {vector<int> coins = {25, 10, 5, 1}; // 美分硬币vector<int> result;for (int coin : coins) {while (amount >= coin) {result.push_back(coin);amount -= coin;}}return result;
}
// 当硬币体系为[25,10,1]时,找30美分将得到25+1+1+1+1+1,而非最优解10+10+10
4.2 正确性验证方法
- 数学归纳法:证明每个选择步骤的局部最优性
- 交换论证法:证明任何最优解都可转换为贪心解
- 拟阵理论:利用组合优化理论验证
五、现代C++实现技巧
5.1 使用STL加速贪心
// 任务调度问题(最多可以参加多少课程)
int maxCourses(vector<pair<int, int>>& courses) {sort(courses.begin(), courses.end(), [](auto& a, auto& b){ return a.second < b.second; });priority_queue<int> pq;int total = 0;for (auto& [dur, end] : courses) {if (total + dur <= end) {total += dur;pq.push(dur);} else if (!pq.empty() && pq.top() > dur) {total += dur - pq.top();pq.pop();pq.push(dur);}}return pq.size();
}
5.2 性能优化实践
// 使用数组代替优先队列(性能提升3倍)
int maxProfit(vector<int>& prices) {int profit = 0;for (int i = 1; i < prices.size(); ++i) profit += max(prices[i] - prices[i-1], 0);return profit;
}
六、贪心算法前沿发展
6.1 在线贪心算法
// 实时数据流处理(最大子数组和)
int maxSubArray(vector<int>& nums) {int curr = 0, maxSum = INT_MIN;for (int num : nums) {curr = max(num, curr + num);maxSum = max(maxSum, curr);}return maxSum;
}
6.2 分布式贪心算法
// 使用OpenMP并行处理大规模数据
#pragma omp parallel for reduction(max:maxProfit)
for (int i = 0; i < n; ++i) {// 并行计算每个子问题的局部最优
}
结语:贪心之道的智慧启示
贪心算法教会我们三个重要启示:
- 把握当下:局部最优的积累可能成就全局最优
- 知止有度:明确算法的适用边界
- 效率优先:在正确性验证后选择最高效方案
当你在LeetCode遇到122. 买卖股票的最佳时机 II时,记住贪心算法能以O(n)时间复杂度完美解决。而面对435. 无重叠区间时,活动选择策略将是最佳选择。
掌握贪心算法,就是掌握化繁为简的算法艺术。在正确的场景下,它能让复杂问题迎刃而解,如同庖丁解牛般优雅高效。
我是福鸦希望这篇博客对你有帮助

相关文章:
贪心算法精解:用C++征服最优解问题
贪心算法精解:用C征服最优解问题 一、贪心算法的本质:当下最优即全局最优 贪心算法如同下棋高手,每一步都选择当前最优的走法。它的核心思想是:通过局部最优选择的叠加,最终得到全局最优解。这种算法在时间复杂度上往…...
《程序员的自我修养—链接、装载与库》-- 对书中常见段的讲解总结
1. 核心段的作用与特点 (1) .text 段(代码段) 内容:存放程序的可执行指令(机器码),例如函数的实现代码。特点: 通常是只读的(防止程序意外修改指令)。在程序运行前已确…...
一文了解汽车图像传感器
2024年底,安森美做了题为"How Automotive Image Sensors Transform the Future of Autonomous Driving"的演讲,这里结合其内容对自动驾驶图像传感器做一个介绍。 当前的自动驾驶感知技术主要有两大技术路线:一种是仅使用摄像头作为传感器进行信息采集的纯…...
2025数据存储技术风向标:解析数据湖与数据仓库的实战效能差距
一、技术演进的十字路口 当前全球数据量正以每年65%的复合增长率激增,IDC预测到2027年企业将面临日均处理500TB数据的挑战。在这样的背景下,传统数据仓库与新兴数据湖的博弈进入白热化阶段。Gartner最新报告显示,采用混合架构的企业数据运营效…...
AI科技公司招聘一位后端开发工程师
招聘岗位:后端开发工程师(兼运维) 公司名称:深圳市格子科技有限公司 公司介绍:深圳市格子科技有限公司作为AI应用创新先锋,构建起以AI工具研发为核心、短剧平台运营为延伸的多业务发展模式。公司自主研发A…...
ubuntu软件
视频软件,大部分的编码都能适应 sudo apt install vlc图片软件 sudo apt install gwenview截图软件 sudo apt install flameshot设置快捷键 flameshot flameshot gui -p /home/cyun/Pictures/flameshot也就是把它保存到一个自定义的路径 菜单更换 sudo apt r…...
《面向对象程序设计-C++》实验一 熟悉Visual C++开发环境及上机过程
一、实验目的 了解和使用VC集成开发环境;熟悉VC环境的基本命令和功能键;熟悉常用的功能菜单命令;学习使用VC环境的帮助;学习完整的C程序开发过程;理解简单的C程序结构。 二、实验内容 使用Visual C 6.0集成环境来编…...
《2025年软件测试工程师面试》MySQL面试题
1、什么是数据库事务? 数据库事务: 是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。 2、Mysql事务的四大特性是什么? 原子性: 事务作为一个整体被执行,包含在其中的对数据…...
Java的 JDBC 编程
1. Java的数据库编程:JDBC JDBC:Java 通过JDBC这样的技术来操作 MySQL MySQL 是一个基于 C/C 实现的数据库。 本身也提供了一系列的 API (Application Progromming Interface),让程序员调用,从而通过代码来…...
Java中的分布式锁:原理、实现与最佳实践
引言 在分布式系统中,多个服务实例或进程需要协调对共享资源的访问。例如,电商系统中库存扣减、金融交易中的余额操作等场景,都需要保证同一时刻只有一个客户端能执行关键操作。**分布式锁(Distributed Lock)**正是解…...
开源!速度100Kb/s的有线和无线双模ESP32S3芯片的DAP-Link调试器
开源!速度100Kb/s的有线和无线双模ESP32S3芯片的DAP-Link调试器 目录 开源!速度100Kb/s的有线和无线双模ESP32S3芯片的DAP-Link调试器本项目未经授权,禁止商用!本项目未经授权,禁止商用!本项目未经授权&…...
深入剖析 Windows 崩溃:从 explorerframe.dll 到 Mwt.exe 的侦探之旅
抱歉复制后格式出现问题,可能是因为 Markdown 或纯文本在不同平台间的换行和缩进处理不一致。我重新整理了一份格式清晰的版本,确保在复制到博客平台(如 WordPress、Medium)或文本编辑器时更容易调整。以下是优化后的 Markdown 版…...
如何将ipynb文件转换为pdf文件
事情起因: 基本我所有的code以及代码注释,以及出图说明都统一放在jupyter notebook中, 代码注释,或者文档说明,实际上就是markdown所做的那一切,都是在markdown中写的; 代码的话,…...
具备多种功能的PDF文件处理工具
软件介绍 在日常办公和学习场景中,PDF文件使用极为频繁,而一款功能强大的PDF编辑软件能大幅提升处理效率。 今天要介绍的Adobe Acrobat Pro DC 2024.005.20414,就具备像编辑Word文档一样便捷编辑PDF的能力。 PDF文档在学习和工作中广泛应用…...
如何做好滚珠导轨的防尘工作?
滚珠导轨滑块在使用过程中,会吸附大量的灰尘和污垢,导致摩擦力增大,使用寿命缩短。那么,我们应该如何做好滚珠导轨的防尘工作呢? 1、使用防护罩:对于外露的滚珠导轨,可安装如螺旋弹簧钢带套管、…...
c语言库 strcpy函数介绍,以及实现
strcpy 函数介绍 strcpy 是 C 语言标准库中的一个字符串处理函数,定义在 <string.h> 头文件中。其作用是将一个字符串的内容从源地址复制到目标地址。 函数原型: char *strcpy(char *dest, const char *src);参数说明: dest…...
nettrace rtt分析器
开源工具学习记录之流程梳理 近期对腾讯的的开源项目: nettrace(网络故障分析工具) ,进行源码学习。 开源仓库:Nettrace开源仓库 开源工具实现注释:nettrace学习记录 Nettrace学习记录之流程梳理Nettrace eBPF程序自动挂载方式探究 nettrace rtt分析器…...
裂变营销策略在“开源链动2+1模式AI智能名片S2B2C商城小程序”中的应用探索
摘要:在当今数字化时代,企业营销手段日新月异,裂变营销作为一种高效的用户增长策略,正逐渐成为众多企业竞相探索的焦点。本文旨在探讨“开源链动21模式AI智能名片S2B2C商城小程序”中裂变营销的应用,通过“分名、分利、…...
VC++ 获取目的IP的路由
GetBestRoute 函数获取到目的IP的最佳匹配路由。 第一个参数为:destination(目的IP) 第二个参数为:source(源IP) 通常不需要指定第二个source,这个一般用来匹配具体某一个网卡接口路由的&…...
WangEditor快速实现版
WangEditor快速实现版 效果 案例代码 后端 package com.diy.springboot.controller;import cn.hutool.core.util.IdUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiImplicitParam; import org.sp…...
Java常见面试技术点整理讲解——后端框架(整理中,未完成)
前言: 对于后端常用框架的技术整理,其实框架在平时就是会用就行,但面试时多半需要描述实现原理,这个要靠自己理解,不推荐死记硬背。 这篇和另外几篇文章区分开,主要用于规整Java后端各种框架,…...
Dify 本地部署教程
目录 一、下载安装包 二、修改配置 三、启动容器 四、访问 Dify 五、总结 本篇文章主要记录 Dify 本地部署过程,有问题欢迎交流~ 一、下载安装包 从 Github 仓库下载最新稳定版软件包,点击下载~,当然也可以克隆仓库或者从仓库里直接下载zip源码包。 目前最新版本是V…...
Python----数据可视化(Seaborn二:绘图一)
常见方法 barplot方法 单独绘制条形图 catplot方法 可以条形图、散点图、盒图、小提亲图、等 countplot方法 统计数量 一、柱状图 seaborn.barplot(dataNone, xNone, yNone, hueNone, colorNone, paletteNone) 函数描述data用于绘图的数据集。x用于绘制长格式数据的输入。…...
加速科技Flex10K-L测试机:以硬核创新重塑显示驱动芯片测试新标杆!
在2024年召开的世界显示产业创新发展大会上,加速科技自主研发的高密度显示驱动芯片测试设备Flex10K-L凭借其突破性技术创新,成功入选"十大创新技术(产品)"。作为国内显示驱动芯片测试领域的标杆性设备,Flex1…...
linux-文本处理命令(echo,cut,sort,uniq,wc,tr,grep)
echo 打印(标准输入输出命令) [rootlocalhost ~]# echo $HOSTNAME-----$引用变量 localhost [rootlocalhost ~]# echo "$HOSTNAME"----“”弱引用符(可以解释特殊含义的字符) localhost [rootlocalhost ~]# echo $HOSTN…...
DeepSeek私有化部署7:openEuler 24.03-LTS-SP1安装Open WebUI
Open WebUI是一个 Open WebUI 是一个可扩展的、功能丰富、用户友好的自托管 AI 平台,专为完全离线运行而设计。 它支持多种 LLM 运行环境,包括 Ollama 和 OpenAI 兼容的 API,并内置了用于 RAG 的推理引擎,是一个强大的 AI 部署解决…...
spring-boot-starter和spring-boot-starter-web的关联
maven的作用是方便jar包的管理,所以每一个依赖都是对应着相应的一个或者一些jar包,从网上看到很多对spring-boot-starter的描述就是“这是Spring Boot的核心启动器,包含了自动配置、日志和YAML。”没看太明白,所参与的项目上也一直…...
群晖DS223 Docker搭建为知笔记
群晖DS223 Docker搭建为知笔记,打造你的专属知识宝库 一、引言 在数字化信息爆炸的时代,笔记软件成为了我们管理知识、记录灵感的得力助手。为知笔记,作为一款专注于工作笔记和团队协作的云笔记产品,以其丰富的功能和便捷的使用体…...
NLP文本分析之依存句法分析(理论及技术实践)
引言 在自然语言处理(NLP)领域中,理解句子的语法结构是实现语义理解的基础。依存句法分析(Dependency Parsing) 作为句法分析的核心任务之一,通过揭示句子中词语之间的依存关系,为机器翻译、信…...
回溯-子集
78.子集 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。输入:整型数组 输出:二元列表 思路:利用二进制&…...
