贪心算法:用C++玩转最优解的艺术(实战宝典)

C++算法篇 贪心算法 1、扑克牌 题目描述 你有n种牌,第i种牌的数目为ci​。另外有一种特殊的牌:joker,它的数目是m。你可以用每种牌各一张来组成一套牌,也可以用一张 joker 和除了某一种牌以外的其他牌各一张组成1套牌。比如,当n=3时,一共有4种合法的套牌:{1,2,3},{J,2,3},{1,J,3},{1,2,J}。给出n,m和ci​,你的任务是组成尽量多的套牌。每张牌最多只能用在一副套牌里(可以有牌不使用)。 输入格式 第一行包含两个整数n,m,即牌的种数和 joker 的个数。... 阅读详情

一、这个算法有点"贪"!

每次听到"贪心算法"这个词,我总会想起自助餐场景——每次都挑最贵的菜拿(虽然最后可能吃不完)。这个算法就像个"聪明的吃货",总是在当前步骤做出最优选择!(划重点)不过要注意,局部最优不等于全局最优哦!就像吃自助餐拿了太多龙虾导致没肚子吃和牛一样(血泪教训)。

二、什么时候该"贪"?

1. 高频应用场景(敲黑板!)

  • 找零钱问题(老板总要准备最少硬币)
  • 最小生成树(普里姆算法就是典型)
  • 哈夫曼编码(压缩文件必备)
  • 任务调度(如何高效利用时间)

2. 适用条件(超级重要!)

  1. 贪心选择性质:局部最优能导向全局最优
  2. 最优子结构:问题可分解为子问题的最优解
  3. 无后效性:选择后不会影响之前的状态

三、C++实战:背包问题

经典案例:部分背包问题

假设你是劫匪(纯属虚构!),背包容量50kg,宝物清单:

宝物重量(kg)价值(万)
黄金1060
翡翠20100
钻石30120

贪心策略代码实现

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Treasure {
    double weight;
    double value;
    double ratio; // 价值重量比
};

bool compare(Treasure a, Treasure b) {
    return a.ratio > b.ratio; // 按价值比降序排列
}

double greedyKnapsack(int capacity, vector<Treasure>& treasures) {
    sort(treasures.begin(), treasures.end(), compare);
    
    double totalValue = 0.0;
    for(auto& t : treasures) {
        if(capacity >= t.weight) {
            totalValue += t.value;
            capacity -= t.weight;
        } else {
            totalValue += t.ratio * capacity;
            break;
        }
    }
    return totalValue;
}

int main() {
    vector<Treasure> treasures = {
        {10, 60}, {20, 100}, {30, 120}
    };
    
    // 计算价值重量比
    for(auto& t : treasures) {
        t.ratio = t.value / t.weight;
    }
    
    int capacity = 50;
    double maxValue = greedyKnapsack(capacity, treasures);
    cout << "最大价值:" << maxValue << "万" << endl; // 输出:240万
    return 0;
}

代码解读(重点!)

  1. 结构体Treasure存储宝物属性
  2. compare函数实现自定义排序规则
  3. 预处理阶段计算价值重量比
  4. 主算法循环处理每个宝物:
    • 能装下就全拿
    • 装不下就按比例拿
  5. 时间复杂度:O(n log n)(主要在排序)

四、为什么有人骂它"目光短浅"?

贪心算法的局限性

  • 不能保证全局最优(比如0-1背包问题)
  • 对问题结构要求严格
  • 需要严格的数学证明(否则可能翻车)

避坑指南(亲测有效!)

  1. 先验证是否满足贪心条件
  2. 尝试构造反例测试
  3. 结合动态规划使用(比如Dijkstra算法)
  4. 当问题具有拟阵结构时可放心使用

五、进阶技巧:如何设计自己的贪心策略

3大设计方向

  1. 价值最大化:每次选价值最高的
  2. 代价最小化:每次选成本最低的
  3. 比例优化:综合多个参数(如价值/重量)

实战心得(血泪经验)

  • 多打印中间结果调试(cout大法好!)
  • 使用priority_queue优化排序
  • 注意浮点数精度问题(比如比较时用epsilon)
  • 活用STL的sort自定义比较函数

六、面试必问:贪心 vs 动态规划

对比表格(背下来!)

特征贪心算法动态规划
决策方式局部最优全局最优
时间复杂度通常较低一般较高
空间复杂度通常O(1)需要存储状态
问题类型优化问题组合问题
回溯能力无有
经典案例霍夫曼编码背包问题

七、你以为这就结束了?

最近在LeetCode刷题时发现个有趣现象:很多看似动态规划的题,用贪心反而更高效!比如:

  • 122.买卖股票的最佳时机 II
  • 455.分发饼干
  • 406.根据身高重建队列

(小声bb)其实算法没有绝对的好坏,就像螺丝刀和扳手,关键看使用场景。下次遇到问题时,不妨先问三个问题:

  1. 能不能贪?
  2. 怎么贪?
  3. 贪得对不对?

最后送大家一句算法界的至理名言:“Greedy is good, when properly applied.” (贪心虽好,可不要贪杯哦~)

3dMax脚本类插件:不写 C++也能造“原生”工具 从plugin关键字到场景持久化,拆解 MAXScript 插件开发全流程! 阅读详情

相关推荐

LabVIEW内存优化实战:用DVR和队列高效处理大型数组,告别数据副本

本文深入探讨LabVIEW内存优化技术,重点介绍数据值引用(DVR)和单元素队列(SEQs)在高效处理大型数组中的应用。通过对比传统方法与现代引用技术的性能差异,提供减少内存副本、提升程序效率的实战方案,帮助开发者在测试测量、图像处理等数据密集型场景中实现显著性能提升。

weixin_30835649的博客 1061

贪心算法(c++)

基本原理:每一步都选择局部最优解,而尽量不考虑对后续的影响,最终达到全局最优解。局限性:贪心算法不能保证获得全局最优解,但在某些问题上具有高效性。特征:贪心选择性质、最优子结构性质(根据我的观察,很多贪心的题目会出现“不同的操作产生的贡献相同”的特征,在此特征下我们每次选择代价最小的。贪心类型多且杂,需要积累联系。二、贪心算法实现步骤1、确定问题的最优子结构(贪心往往跟排序、优先队列等一起出现)。

2301_77138117的博客 7136

VS2022如何兼容老项目?.NET Framework 4.0/4.5安装避坑指南

本文提供了在Visual Studio 2022中兼容和维护.NET Framework 4.0/4.5等老旧项目的完整解决方案。针对VS2022无法直接识别旧框架的核心问题,文章详细剖析了原因,并重点推荐通过官方NuGet包安全获取引用程序集的方法,给出了从下载、解压到部署至标准目录的详细步骤。同时,文章还深入探讨了项目文件格式过旧、NuGet包还原失败等进阶问题的排查与解决策略,旨在帮助开发者高效、稳定地在现代开发环境中维护历史代码库。

weixin_27734811的博客 513

<C/C++算法>贪心策略练习与总结

一.感性认识“贪心策略” 1.基本概念 所谓贪心算法是指,在对问题求解时,总是只做出在当前看来是最好的选择即可,并不穷尽各种可能来真正找出最优解。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

EbowTang的练习场 8402

Score Matching(得分匹配)

Score Matching(得分匹配)是一种统计学习方法,用于估计概率密度函数的梯度(即得分函数),而无需知道密度函数的归一化常数。这种方法由Hyvärinen在2005年提出,主要用于无监督学习,特别是在密度估计和生成模型中。

weixin_39699362的博客 2167

ADS使用Smith圆图进行阻抗匹配

在处理RF系统的实际应用问题时,总会遇到一些非常困难的工作,对各部分级联电路的不同阻抗进行匹配就是其中之一。一般情况下,需要进行匹配的电路包括天线与低噪声放大器(LNA)之间的匹配、功率放大器输出(RFOUT)与天线之间的匹配、LNA/VCO输出与混频器输入之间的匹配。匹配的目的是为了保证信号或能量有效地从“信号源”传送到“负载”。 阻抗匹配(impedance matching) 信号源内阻与所接传输线的特性阻抗大小相等且相位相同,或传输线的特性阻抗与所接负载阻抗的大小相等且相位相同,分别称为传输线的输

红茶绿茶和奶茶的博客 3万+

C++信息学奥赛真题深度研习:从算法原理到实战技巧

算法与数据结构是计算机科学的核心基础,其原理在于通过高效的数据组织和计算步骤解决复杂问题。掌握经典算法如动态规划、深度优先搜索(DFS)和贪心算法,能极大提升程序效率与问题解决能力,在竞赛编程、软件开发等领域具有极高技术价值。这些算法广泛应用于路径规划、资源优化、组合枚举等场景。本文聚焦信息学奥赛真题,通过系统讲解**五步拆题法**和**对拍调试技术**,深入剖析如何将算法原理转化为解决实际竞赛问题的实战能力,帮助选手实现从理解到应用的跨越。

weixin_30512043的博客 360

什么是深度展开网络?如何将迭代算法的每一次迭代展开成深度网络对应的一层?深度展开网络进行端对端训练,其中端对端是什么意思?

在深度学习和机器学习的背景下,“端到端”(End-to-end)训练指的是将输入数据直接映射到最终输出的过程,而不需要任何中间的手动数据预处理或特征工程。- **自然语言处理**:端到端自然语言处理系统可以将自然语言输入直接转化为计算机可理解的语言输出,而不需要对语言进行分解和转化。- **推荐系统**:通过使用深度神经网络,端到端推荐系统可以直接根据用户历史行为预测其未来的兴趣爱好,并推荐相应的产品或服务。4. **直接映射**:从输入到输出的直接映射,中间没有任何拆分或分解的过程。

m0_67897882的博客 5426

【贪心算法专题】贪心算法入门:从“鼠目寸光”到两道经典例题(柠檬水找零 &将数组和减半的最少操作次数)

贪心策略是一种解决问题的策略:从局部最优推向全局最优。具体执行时可以拆成三步:把解决问题的过程分为若干步;解决每一步的时候,都选择当前看起来"最优"的解法;"希望"最终能得到全局最优解。这里的关键词是"希望"。贪心不像动态规划那样有明确的状态转移保证,它只是做了一个看起来很合理的选择,至于这个选择最终能不能通向全局最优,是需要单独证明的。

2501_93351213的博客 376

Test-Time Adaptation Induces Stronger Accuracy and Agreement-on-the-Line

TTA不管是否提高了OOD的泛化性都增强了线性的趋势,TTA的初始目的是为了增强OOD的表现,一个人可能会觉得TTA使得ACL更强的原因是他消除了ID和OOD之间的差距,因此所有模型间ID vs OOD的准确率接近于y=x这条线,但是实际上这个解释不能够反映我们的经验发现,因为虽然TTA将分布之间的偏移简化为一种放缩的分布,但是这个放缩的因子幅值可能很大,也就是α<<1但是r>>1,这就会导致很偏离y=x这条线,而且理论分析也是,虽然ID和OOD的差距很大,但是线性关系还在。

m0_62673638的博客 148

腾讯面试——机器学习岗面试总结

先写合并两个有序数组,接着写合并n个有序的数组,假设总共m个数,讲了一个思路两两合并直到只剩下一个数组,分析一下时间复杂度(MlogN),面试官不满意,然后想了一下说了另一个思路,用n个指针开始指向各个数组的首端,用一个优先队列维护他们的最小值,每次拿出最小值的指针然后插入该指针的下一个值。感觉跟二面面试官聊得还是挺开心的,他详细地介绍了他们部门所做的业务,然后问了一下什么时候能来实现,我说只能暑假七八两个月,他觉得有点晚,这样子不利于转正,有些人都实习半年的,回去讨论一下,正式批之前给我答复。

FPGA/MATLAB学习教程/源码/项目合作开发 1230

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 187

Debezium报错处理系列之二十一:Unable to connect: Communications link failure.The driver has not received any

Debezium报错系列之二十一:Unable to connect: Communications link failure.The driver has not received any。

zhengzaifeidelushang的博客 546

选型笔记:Type‑C 扩展坞方案评估|DP1.4 转 HDMI2.0 桥接芯片 GSV2201S@ACP

本文记录 GSV2201S 这款 DP1.4a 转 HDMI2.0 桥接芯片评估,梳理视频、HDCP、PD 集成能力,总结 Type‑C 转接 Dongle、扩展坞方案的适配边界,以及差分走线、PD 时序、HDCP 握手等高频调试问题,为 C 口视频转接方案选型提供参考。

ACP广源盛的博客 217

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 385

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 332

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:倍增法求最近公共祖先LCA解析

蓝桥杯报名正在火热进行(软件赛报名 2026-10-08—12-18,省赛 2027-04-10),电子学会 12 月软件编程(C/C++ 一级至十级、Python 一级至六级)考级报名也已开启(9/23—12/2),全国青少年信息素养大赛算法应用主题赛同步推进——把 LCA 这个模板练熟,正是冲刺这些赛事树型考点的关键一步。所谓「最近公共祖先」:在一棵以某个节点为根的树里,两个节点 u、v 向上追溯,最早交汇的那个祖先就叫它们的 LCA。比如家谱里,你和你表哥最近的共同长辈就是你们的祖父。

IT_Scratch的博客 532

C++ 多态详解:作用、原理与实战用法

多态是C++面向对象的核心特性,通过虚函数实现运行期动态绑定,使同一接口在不同对象上表现出不同行为。其核心作用包括统一接口、提升可扩展性、降低耦合、支持运行时分派与批量处理。实现依赖虚函数表(vtable)和虚指针(vptr),需注意虚析构函数、对象切片等陷阱。相比编译期多态(模板),运行期多态灵活性高但有调用开销。合理结合两者,可兼顾代码的灵活性与性能,是构建可扩展、低耦合系统的关键。

2402_85743155的博客 376

【C语言】字符与字符串函数

C语言中字符串为以\0结尾的字符数组,标准库函数基于此约定。本文解析字符串内存布局,详解ctype.h与string.h中字符分类、长度计算、拷贝、比较等函数的使用要点,强调长度判断与越界风险,最后通过命令行待办事项示例整合fgets、sscanf、strncpy、strcmp,展示实际应用中的关键细节。

记录在学习过程中学到的知识 340

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 300

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 435

C++ 求抛物线的顶点、焦点和准线(Finding the vertex, focus and directrix of a parabola)

已知抛物线方程 $ y = ax^2 + bx + c $,可利用公式求其顶点、焦点和准线。顶点为 $ \left( -\frac{b}{2a}, \frac{4ac - b^2}{4a} \right) $,焦点为 $ \left( -\frac{b}{2a}, \frac{4ac - b^2 + 1}{4a} \right) $,准线方程为 $ y = c - \frac{b^2 + 1}{4a} $。以 $ a=5, b=3, c=2 $ 为例,计算得顶点 $(-0.3, 1.55)$,焦点 $(-0

csdn_aspnet的专栏,请点击博客主页右上角三个点中的私信联系 163

c++ 超级大坑未定义行为如何避免(下)

尤其是通过。

拒绝AI文,努力在AI时代写出感动人心的好文章 141

C 语言指针与输入输出

指针是 C 语言的魂,输入输出是和人交互的入口。这篇文章把"变量在内存里到底长什么样"讲透,接着用代码验证原码/反码/补码为什么非用补码不可,再拿进制转换、数组、printf/scanf 的格式符收尾。所有输出都是本机 gcc 真实跑出来的。

2401_89953644的博客 158

从“不照人”到“剂量达标”:扇叶遮挡式UV-C空气消毒的工程边界与可验证评估框架

人机共存”正逐渐成为家用 UV-C 空气消毒产品的核心卖点。其中一类常见结构,是把 254 nm 紫外线灯置于吊扇扇叶上方,以扇叶盘作为物理遮挡,同时借助风扇强制对流实现空气循环消毒。专利文献对该结构的意图描述相当清晰:消毒平台遮挡紫外线灯朝下发出的光,使光线射向天花板,从而“不会让紫外线辐射到位于吊扇灯下方的用户”。然而,“结构上不直射”与“工程上安全且有效”之间,仍隔着一段需要实测数据来填补的距离。

HANDY09200的博客 692

C 语言 malloc() 详解与实战 Demo

本文详解C语言malloc()函数,涵盖其语法、内存原理及实战应用。通过动态整数、数组、结构体与链表的Demo,演示如何安全申请、使用与释放内存,强调避免内存泄漏与空指针检查的重要性,帮助开发者掌握动态内存管理核心技能。

tangPHP的博客 364
上一篇: 手把手教你搞定Git冲突!程序员必备的协作生存技能(附真实案例)
下一篇: Python零基础入门到精通的完整指南(手把手带你飞!)
普通网友
博客等级 码龄2年 89粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值