c++中如何实现背包问题_c++ 01背包动态规划解法

发布时间 - 2026-01-02 00:00:00    点击率:
二维dpi定义最稳妥,因逻辑清晰、不易出错;初始化全0即可满足边界条件;转移时需判断j≥weight[i-1]避免越界;一维优化须倒序遍历以防重复选取。

为什么 dp[i][j] 定义成「前 i 个物品、容量为 j 时的最大价值」最稳妥

很多初学者会尝试用 dp[j] 一维数组直接推,但容易搞错遍历顺序或覆盖未使用的状态。二维定义虽然多占空间,但逻辑清晰、不易出错,尤其在调试和理解转移关系时更可靠。

关键点在于:每个物品只能选 0 次或 1 次,所以状态转移必须区分「不选第 i 个」和「选第 i 个」两种情况:

  • 不选:dp[i-1][j]
  • 选(前提是 j >= weight[i-1]):dp[i-1][j - weight[i-1]] + value[i-1]

注意物品数组通常从 0 开始索引,所以第 i 个物品对应 weight[i-1]value[i-1]

如何正确初始化 dp 数组并避免越界访问

初始化时,dp[0][j] 表示「前 0 个物品」能装下的最大价值,显然全为 0;dp[i][0] 表示「容量为 0」时的价值,也全为 0。但实际编码中,只要把整个 dp 数组初始化为 0,就能自然满足这两个边界条件。

真正容易出错的是状态转移中的下标检查:

  • 必须判断 j >= weight[i-1] 才能尝试选择第 i 个物品,否则跳过
  • 二维数组大小应为 (n+1) x (W+1),其中 n 是物品数量,W 是背包容量
  • 如果用 vector>,记得先 resize 正确维度,否则运行时可能崩溃

一维优化版 dp[j] 的核心约束和遍历方向

一维写法节省空间,但必须倒序遍历容量 j(从 Wweight[i-1]),否则会重复使用刚更新过的值,导致一个物品被多次选取(退化成完全背包)。

常见错误现象:dp[W] 结果明显偏大,甚至超过所有物品价值之和——大概率是正向遍历了 j

实操建议:

  • 初始化 vector dp(W+1, 0)
  • 外层循环 i 从 0 到 n-1
  • 内层循环 jW 降序到 weight[i](含)
  • 转移式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
#include 
#include 
using namespace std;

int knapsack01(const vector& weight, const vector& value, int W) { int n = weight.size(); vector> dp(n + 1, vector(W + 1, 0));

for (int i = 1; i zuojiankuohaophpcn= n; ++i) {
    for (int j = 0; j zuojiankuohaophpcn= W; ++j) {
        dp[i][j] = dp[i-1][j]; // 不选第 i 个
        if (j >= weight[i-1]) {
            dp[i][j] = max(dp[i][j], dp[i-1][j - weight[i-1]] + value[i-1]);
        }
    }
}
return dp[n][W];

}

一维优化看似简洁,但一旦数据规模变大或需要输出具体选了哪些物品,二维结构反而更容易回溯路径。别为了省几 MB 内存,让逻辑变得脆弱。


# go  # 编码  # c++  # 为什么  # 循环  # 遍历  # 不选  # 的是  # 就能  # 两种  # 要把  # 这两个  # 更容易  # 则会  # 选了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  如何快速搭建FTP站点实现文件共享?  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  黑客如何通过漏洞一步步攻陷网站服务器?  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  Laravel怎么为数据库表字段添加索引以优化查询  黑客入侵网站服务器的常见手法有哪些?  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  Laravel如何实现事件和监听器?(Event & Listener实战)  Laravel如何从数据库删除数据_Laravel destroy和delete方法区别  Laravel如何集成Inertia.js与Vue/React?(安装配置)  音乐网站服务器如何优化API响应速度?  Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】  Android仿QQ列表左滑删除操作  如何基于PHP生成高效IDC网络公司建站源码?  微信小程序 配置文件详细介绍  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)  Laravel如何自定义分页视图?(Pagination示例)  简单实现Android验证码  Laravel API资源类怎么用_Laravel API Resource数据转换  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  js代码实现下拉菜单【推荐】  北京专业网站制作设计师招聘,北京白云观官方网站?  Laravel如何实现数据库事务?(DB Facade示例)  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】  Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理  历史网站制作软件,华为如何找回被删除的网站?  JavaScript如何实现继承_有哪些常用方法  实现点击下箭头变上箭头来回切换的两种方法【推荐】  如何在IIS7上新建站点并设置安全权限?  如何在万网主机上快速搭建网站?  Laravel集合Collection怎么用_Laravel集合常用函数详解  如何挑选最适合建站的高性能VPS主机?  Laravel怎么集成Vue.js_Laravel Mix配置Vue开发环境  如何用AI帮你把自己的生活经历写成一个有趣的故事?  如何在橙子建站中快速调整背景颜色?  如何用花生壳三步快速搭建专属网站?  如何在阿里云部署织梦网站?  如何用VPS主机快速搭建个人网站?  logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  JS弹性运动实现方法分析  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】