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

贪心算法之船舶装载问题

一、问题引入

        船舶装载问题是经典的贪心算法应用场景,核心目标是:在给定船舶最大载重量的限制下,计算出最多能装载的物品数量。该问题的关键在于如何选择物品装载顺序,以实现 “数量最多” 的目标,而贪心算法通过 “每次选最优” 的策略高效解决此问题。

二、贪心算法原理

1. 核心思路

        贪心算法的核心思想是 “局部最优 → 全局最优”。针对船舶装载问题,“局部最优” 即每次选择当前剩余物品中重量最轻的物品进行装载,因为选择轻的物品能最大限度地节省载重量空间,从而为后续装载更多物品创造条件,最终实现 “装载数量最多” 的全局最优目标。

2. 算法步骤

  1. 输入物品数量、船舶最大载重量以及每个物品的重量。
  2. 将所有物品按重量升序排序(关键步骤,为 “选最轻” 提供基础)。
  3. 从排序后的物品中,依次选取物品并累加重量,直到累加重量超过最大载重量为止。
  4. 统计并返回已装载的物品数量

三、代码结构与优化分析

1. 原始代码核心逻辑

        原始代码通过 main 函数完成输入、排序调用和结果计算,maxLoad 函数实现装载数量统计,但存在可读性差、安全性低等问题,具体表现为:

1. 输入提示与计算逻辑混杂在main函数中,代码冗余。

2. 使用原始数组存储物品重量,存在固定大小限制,灵活性不足。

3. 缺乏输入验证,若用户输入非法值(如负数、非数字),程序可能崩溃。

2. 优化后代码解析

        优化后的代码基于 C++ 实现,解决了原始代码的缺陷,结构更清晰、安全性更高,具体代码及核心模块分析如下:

(1)头文件依赖
#include <iostream> // 输入输出流
#include <algorithm> // 包含sort排序函数
#include <vector> // 动态数组,替代原始数组
using namespace std;
(2)核心函数 1:maxLoad(计算最大装载数量)
int maxLoad(const vector<double>& weights, double capacity) {double total = 0.0; // 已装载物品总重量int count = 0; // 已装载物品数量// 遍历排序后的物品(范围for循环,C++11及以上特性)for (const auto& weight : weights) {if (total + weight <= capacity) { // 若能装下当前物品total += weight;++count;} else {break; // 超过载重量,停止装载}}return count;
}

关键优化点

  • 用vector<double>替代原始数组:动态调整大小,避免固定长度限制,提高灵活性。
  • const修饰符:确保weights数组在函数内不被修改,提升代码安全性。
  • 引用传递(& weights):避免数组拷贝,提高程序运行效率。
(3)核心函数 2:inputWeights(单独处理输入逻辑)
void inputWeights(vector<double>& weights, int n) {cout << "请输入" << n << "个物品的重量: ";for (int i = 0; i < n; ++i) {cin >> weights[i];}
}

关键优化点

        输入逻辑与main函数分离:使main函数更简洁,代码可读性提升,后续维护时可单独修改输入逻辑。

(4)main函数
int main() {int n; // 物品数量double capacity; // 船舶最大载重量cout << "请输入物品数量和船的最大载重量: ";cin >> n >> capacity;vector<double> weights(n); // 动态数组存储物品重量inputWeights(weights, n); // 调用输入函数sort(weights.begin(), weights.end()); // 升序排序(核心步骤)// 输出结果cout << "最多能装载的物品数量: " << maxLoad(weights, capacity) << endl;return 0;
}

        执行流程:输入参数→获取物品重量→排序→计算装载数量→输出结果,流程清晰,符合 “贪心算法步骤”。

3. 进一步可优化方向(补充建议)

  • 添加输入验证:在inputWeights和main函数中增加判断,如物品数量n需为正整数、物品重量和载重量需为非负数,避免非法输入导致程序异常,示例代码:
// 输入物品数量时验证
while (cin >> n >> capacity, n <= 0 || capacity < 0) {cout << "输入无效!物品数量需为正整数,载重量需非负,请重新输入:";
}// 输入物品重量时验证
while (cin >> weights[i], weights[i] < 0) {cout << "物品重量不能为负,请重新输入:";
}
  • 支持浮点数精度控制:若实际场景中对重量精度有要求(如保留 2 位小数),可使用fixed和setprecision控制输出,需添加头文件#include <iomanip>。

四、复杂度分析

1. 时间复杂度

  • 排序操作:使用 C++ 标准库 sort 函数,时间复杂度为 O(n log n)。
  • 遍历计算:maxLoad 函数中遍历 vector 数组,时间复杂度为 O(n)。
  • 整体复杂度:排序是耗时最长的操作,因此整体时间复杂度为 O(n log n),适用于中等规模数据(如 n≤10⁵),效率较高。

2. 空间复杂度

  • 主要空间消耗来自存储物品重量的vector数组,空间复杂度为O(n)。
  • 无额外复杂数据结构,空间利用率高。

五、核心知识点总结

  1. 贪心算法在船舶装载问题中的应用逻辑:“选最轻物品 → 最大化装载数量”,核心是排序后依次选择;
  2. C++ 代码优化技巧:用vector替代原始数组、函数拆分(输入与计算分离)、const修饰符与引用传递;
  3. 复杂度关键:排序决定时间复杂度,数组存储决定空间复杂度;
  4. 工程化改进:输入验证、精度控制等细节可提升代码健壮性。
http://www.dtcms.com/a/398433.html

相关文章:

  • 面试_常见大厂面试题
  • 网站地图怎么建设wordpress文章页样式修改
  • 网站如何做交互热门seo推广排名稳定
  • 【第29话:路径规划】自动驾驶启发式搜索算法(A星搜索算法( A* 搜索算法))详解及代码举例说明
  • React学习教程,从入门到精通,React Router 语法知识点及使用方法详解(28)
  • Docker Compose 从入门到实践
  • D3.js 与数据可视化
  • RNA-seq分析之最佳cutoff(TCGA版)
  • 浏览器直接进入网站的注意事项钢筋网片价格
  • scrapy-redis项目:爬取某网站图书信息
  • (论文速读)DiffBlender:可组合和通用的多模态文本到图像扩散模型
  • 第三方网站测试工具:【Postman使用基础指南】
  • Pytest+requests进行接口自动化测试5.0(5种assert断言的封装 + pymysql)
  • C# MVC 模型绑定全解析:从基础机制到自定义绑定器实战指南
  • 企业网站网页设计专业的团队网站建设
  • 网站建设可上传视频的wordpress 数据库类型
  • 广州南沙区建设和交通局网站个人建立网站要多少钱
  • Vue3 》》vite》》vite-plugin-mock mock 模拟数据 ,loadEnv
  • 宝塔面板搭建RustDesk教程:告别命令行,一键拥有私有远程桌面
  • Docker + IDEA 一键部署!
  • Rust开源HyperSwitch实战指南
  • Chrome性能优化指南
  • Chrome高危类型混淆0-Day漏洞(CVE-2025-10585)技术分析
  • 教做面点的网站广州百度竞价托管
  • 网站推广方案合肥房产网安居客
  • 【算法专题训练】24、单调栈
  • 【开题答辩全过程】以 IRWT考试预约系统为例,包含答辩的问题和答案
  • 在字典和列表相互嵌套的结构体中搜索指定元素
  • 文献阅读 | iMetaMed | FigureYa:一个标准化可视化框架,用于增强生物医学数据解释和研究效率
  • wordpress自由拖拽同ip网站做排名seo