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

【C++】01背包问题暴力,记忆,动态规划解法

0-1 背包问题详解与实现

目录

  • 0-1 背包问题详解与实现
    • 问题描述
    • 问题分析
      • 状态定义
      • 状态转移方程
      • 边界条件
      • 算法实现
      • 暴力搜索
      • 记忆化搜索
      • 动态规划
      • 空间优化
    • 总结
    • 思维导图
    • C++学习资源

问题描述

在算法领域,0-1背包问题是一个经典的优化问题。给定一个背包和一个物品集合,每个物品有其重量和价值,我们需要选择物品放入背包,使得背包内物品的总价值最大,同时不超过背包的容量限制。

问题分析

0-1背包问题可以通过决策树模型来理解。每件物品都有放入或不放入背包的选择,我们可以定义状态来描述这一决策过程。

状态定义

  • 状态[i, c]:考虑前i个物品,在容量为c的背包中能获得的最大价值。

状态转移方程

  • 不放入物品idp[i, c] = dp[i-1, c]
  • 放入物品idp[i, c] = dp[i-1, c-wgt[i-1]] + val[i-1]
  • 最终状态dp[n, cap]即为所求的最大价值。

边界条件

  • 当无物品或背包容量为0时,最大价值为0。

算法实现

我们可以通过递归、记忆化搜索和动态规划三种方式来解决0-1背包问题。

暴力搜索

int bag01(vector<int>& wgt, vector<int>& val, int i, int c) {if (i == 0 || c == 0) return 0;if (wgt[i - 1] > c) return bag01(wgt, val, i - 1, c);int no = bag01(wgt, val, i - 1, c);int yes = bag01(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1];return max(no, yes);
}

记忆化搜索

int bag01Mem(vector<int>& wgt, vector<int>& val, vector<vector<int>>& mem, int i, int c) {if (i == 0 || c == 0) return 0;if (mem[i][c] != -1) return mem[i][c];if (wgt[i - 1] > c) return bag01Mem(wgt, val, mem, i - 1, c);int no = bag01Mem(wgt, val, mem, i - 1, c);int yes = bag01Mem(wgt, val, mem, i - 1, c - wgt[i - 1]) + val[i - 1];mem[i][c] = max(no, yes);return mem[i][c];
}

动态规划

int bag01DP(vector<int>& wgt, vector<int>& val, int cap) {int n = wgt.size();vector<vector<int>> dp(n + 1, vector<int>(cap + 1, 0));for (int i = 1; i <= n; i++) {for (int c = 1; c <= cap; c++) {if (wgt[i - 1] > c) {dp[i][c] = dp[i - 1][c];} else {dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]);}}}return dp[n][cap];
}

空间优化

通过倒序遍历和去除第一维,我们可以优化空间复杂度。

int bag01DPm(vector<int>& wgt, vector<int>& val, int cap) {int n = wgt.size();vector<int> dp(cap + 1, 0);for (int i = 1; i <= n; i++) {for (int c = cap; c >= 1; c--) {if (wgt[i - 1] <= c) {dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]);}}}return dp[cap];
}

总结

0-1背包问题是算法学习中的一个重要问题,通过不同的方法实现,我们可以更好地理解递归、记忆化搜索和动态规划的概念和应用。

思维导图

下面是0-1背包问题的思维导图,展示了不同算法之间的关系和转换过程。

0-1背包问题
暴力搜索
记忆化搜索
动态规划
空间优化
递归实现
避免重复计算
状态转移
倒序遍历
减少空间复杂度

C++学习资源

以下是我学C++觉得不错的资料,仅供学习:
匠心精作C++从0到1入门编程-学习编程不再难
链接: https://pan.baidu.com/s/1q7NG28V8IKMDGD7CMTn2Lg?pwd=ZYNB 提取码: ZYNB
第二套、侯捷老师全系列八部曲 - 手把手教你进阶系列
链接: https://pan.baidu.com/s/1AYzdguXzbaVZFw1tY6rYJQ?pwd=ZYNB 提取码: ZYNB

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 算法笔记|Day26贪心算法IV
  • [C#]将opencvsharp的Mat对象转成onnxruntime的inputtensor的3种方法
  • 【python报错】‘XXX‘ object is not callable
  • 性能基础之硬盘性能知识必知必会
  • 电容电阻电感关于封装的选型
  • 每天一个数据分析题(四百九十三)- 主成分分析与因子分析
  • C++ STL find 用法
  • Linux 部署YUM仓库及NFS共享服务
  • spring低版本设置cookie的samesite属性
  • roles
  • 力扣热题100_回溯_22_括号生成
  • openstack基本操作
  • windows平台的postgresql主从数据库流备份
  • UNiapp之微信小程序导出Excel
  • PCIe学习笔记(25)
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • Android框架之Volley
  • co模块的前端实现
  • git 常用命令
  • golang中接口赋值与方法集
  • HashMap ConcurrentHashMap
  • Hibernate【inverse和cascade属性】知识要点
  • Java到底能干嘛?
  • Less 日常用法
  • python大佬养成计划----difflib模块
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • vagrant 添加本地 box 安装 laravel homestead
  • Vue.js 移动端适配之 vw 解决方案
  • 订阅Forge Viewer所有的事件
  • 工程优化暨babel升级小记
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 一道闭包题引发的思考
  • 如何正确理解,内页权重高于首页?
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​必胜客礼品卡回收多少钱,回收平台哪家好
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • $$$$GB2312-80区位编码表$$$$
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (1)(1.11) SiK Radio v2(一)
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (done) 两个矩阵 “相似” 是什么意思?
  • (SpringBoot)第二章:Spring创建和使用
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)php新闻发布平台 毕业设计 141646
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (强烈推荐)移动端音视频从零到上手(下)
  • (全注解开发)学习Spring-MVC的第三天
  • (三)uboot源码分析
  • (顺序)容器的好伴侣 --- 容器适配器
  • (四)JPA - JQPL 实现增删改查
  • (转)VC++中ondraw在什么时候调用的
  • (转)清华学霸演讲稿:永远不要说你已经尽力了