news 2026/9/26 3:30:16

贪心算法经典例题:背包问题(C++ 代码逐行讲解)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
贪心算法经典例题:背包问题(C++ 代码逐行讲解)

1. 题目背景

这段代码解决的是经典的部分背包问题(Fractional Knapsack):给定x件物品,每件物品有质量m和价值v,背包容量为y,要求在不超过背包容量的前提下,使装入背包的物品总价值最大。

与 0-1 背包不同,这里的物品可以分割(比如大米、面粉、金砂),所以我们可以按比例取走一部分,这就让贪心策略成为可能。

2. 核心思路:贪心策略

贪心的关键在于性价比——单位质量的价值(v / m)。我们总是优先选择「单位价值最高」的物品,能全装就全装,装不下就按剩余容量取一部分,直到背包装满。

这个策略之所以正确,是因为物品可分割:只要每次都拿当前性价比最高的,最终一定能得到全局最优解。

3. 代码逐行讲解

3.1 结构体与全局数组

structValue{floatm;// 物品质量floatv;// 物品价值};Value values[105];// 最多 105 件物品

定义结构体Value保存每件物品的质量m和价值v,并用全局数组values存储所有物品。

3.2 排序比较函数

boolcmp(Value a,Value b){returna.v>b.v;// 按单位价值降序排列}

这是sort的比较函数。注意:在main中已经提前把v变成了「单位价值」(v / m),所以这里直接按v降序排序即可,性价比高的物品排在前面。

3.3 主函数:输入与预处理

intx,y;cin>>x>>y;// x 件物品,背包容量 yfor(inti=0;i<x;i++){cin>>values[i].m;// 输入质量cin>>values[i].v;// 输入价值}for(inti=0;i<x;i++){values[i].v/=values[i].m;// 计算单位价值 v/m}

先读入物品数量和背包容量,再读入每件物品的质量与价值。随后把每件物品的v原地更新为单位价值(v / m),为排序做准备。

3.4 排序

sort(values,values+x,cmp);

按单位价值从高到低排序,性价比最高的物品排在最前面。

3.5 贪心装入

floatsum=0;for(inti=0;i<x;i++){if(values[i].m<=y){// 当前物品能整件装下sum+=values[i].m*values[i].v;// 全装,价值 = 质量 × 单位价值y-=values[i].m;// 剩余容量减少}else{// 装不下整件,只能装一部分sum+=y*values[i].v;// 用剩余容量 y 乘以单位价值break;// 背包已满,结束}}printf("%.2f",sum);// 保留两位小数输出最大总价值

这是核心循环:

  • 若当前物品质量m不超过剩余容量y,就整件装入,累加价值m × v(此时v是单位价值),并扣减剩余容量;
  • 若装不下整件,就按剩余容量取一部分,累加y × v,然后break结束——因为背包已经满了,后面的物品即使性价比再高也装不进去了。

最后用printf("%.2f", sum)保留两位小数输出结果。

4. 复杂度分析

  • 时间复杂度:排序为O(x log x),贪心装入为O(x),整体O(x log x)。
  • 空间复杂度:O(x),用于存储物品数组。

5. 易错点提醒

  1. 单位价值要提前算好:排序前必须把v更新为v / m,否则排序依据错误。
  2. 浮点精度:m、v用float,计算v / m时注意类型,避免整数除法丢失小数。
  3. break不能漏:当装不下整件、只能取一部分时,背包已满,必须跳出循环,否则会继续错误累加。
  4. 输出格式:题目要求保留两位小数,用printf("%.2f", sum)或cout << fixed << setprecision(2)。

6. 总结

这段代码是贪心算法处理部分背包问题的经典实现:先算性价比(单位价值),按性价比降序排序,再依次装入,装不下就取一部分。理解「物品可分割」这一前提,是理解整个贪心策略正确性的关键。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/26 3:29:30

PyCharm 配 TaoToken:连接 Hive 数据库的配置骨架与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 3:27:44

Laravel大文件导出超时解决方案:异步队列与进度轮询实战

1. 先说我为什么把“调大超时时间”这条最顺的路直接否掉了前两个月接到一个紧急工单&#xff0c;运营同事要导三周的订单明细&#xff0c;页面转了四十多秒直接变成504&#xff0c;用户侧看到的就是一个转圈几十秒后报错的页面。我看了眼订单表&#xff0c;当时大概一千两百万…

作者头像 李华
网站建设 2026/9/26 3:27:44

云瞰平台栅格级网络优化实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/26 3:27:18

老i686机器上部署MySQL 4.1.18:二进制tar包实战指南

简介&#xff1a;这份资源是 MySQL 4.1.18 的 Linux 二进制安装包&#xff0c;面向需要在 PC 架构 Linux 系统上搭建关系型数据库的初学者与小型项目开发者。它基于 GNU 工具链并依赖 glibc23 库&#xff0c;解压后即可按官方文档完成配置与安装&#xff0c;省去自行编译的繁琐…

作者头像 李华