01背包问题


问题描述

给定 N 种物品和一个最大载重量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。
问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?

问题分析

对于每个物品,只能选择装或者不装,不能选择只装物体的一部分,因此不能使用单位重量的价值进行排序的方法(贪心)来解决,需要用到动态规划来解决。


动态规划的三个核心

  1. 最优子结构
  2. 边界
  3. 状态转移方程

对于该问题而言,由于第i+1件物品只有两种选择(选与不选),因此前i+1件产品的最优解就是,子结构就是前i件物品装在承重为j的容器中,可以用result[i][j]来表示。

边界就是在只装第一件物品时的情况。

通过上面的对子结构的分析,可以得到状态转移方程:
1. j < w[i]时,即剩余载重量不足以装下当前物品,应有最优解即是前i-1件时的解,result[i][j] = result[i-1][j]
2. j >= w[i]时,即还可以装下当前物品,因此解应为 装与不装 当前物品两种情况中的最大解。如果不装,即result[i-1][j];如果装,,即result[i-1][j-w[i]] + v[i]。因此取最大值结果为result[i][j] = max( result[i-1][j], result[i-1][j-w[i]] + v[i] )


代码

1.二维数组

int getLargestValue_1( vector<int> & v, vector<int> & w, int c ) {vector< vector<int> > res( N+1, vector<int>( c+1, 0 ) );/*  该处初始化边界可以省略由于开始的一列为0,不影响结果  *//*for( int i = 1; i <= c; i++ ) {if( i < w[i] ) {res[1][i] = 0;} else {res[1][i] = v[1];}}*/for( int i = 1; i <= N; i++ ) {  //遍历所有物品for( int j = 1; j <= c; j++ ) {  //遍历容器容量if( j < w[i] ) {  //放不下res[i][j] = res[i-1][j];} else {  //放的下res[i][j] = max( res[i-1][j], res[i-1][j-w[i]] + v[i] );}}/* 输出遍历每件物品的结果 *//* for( int j = 1; j <= c; j++ ) {cout << res[i][j] << ' ';}cout << endl; */}return res[N][c];
}

2.两个一维数组

由于每次遍历之用到了当前行与上一行,因此可优化空间到两个一维数组。

int getLargestValue_2( vector<int> & v, vector<int> & w, int c ) {vector<int> preResult( c+1, 0 );  //存储上次得到的结果,对应上一行vector<int> result( c+1, 0 );  //存储当前行结果for( int i = 1; i <= N; i++ ) {for( int j = 1; j <= c; j++ ) {if( j < w[i] ) {result[j] = preResult[j];} else {result[j] = max( preResult[j], preResult[j-w[i]] + v[i] );}}for( int j = 1; j <= c; j++ ) {cout << preResult[j] << ' ';}cout << endl;preResult = result;}return result[c];
}

3. 一维数组

我们还可以发现每次使用的都是上一行当前列元素上面与左面的元素(preResult[j], preResult[j-w[i]] ),因此我们可以将每行的遍历顺序改变,即从右向左计算,即可将每次的计算结果直接覆盖到当前位置。

int getLargestValue_3( vector<int> & v, vector<int> & w, int c ) {vector<int> result( c+1, 0 );for( int i = 1; i <= N; i++ ) {for( int j = c; j > 0; j-- ) {  //从右向左计算if( j >= w[i] ) {result[j] = max( result[j], result[j-w[i]] + v[i] );}}}return result[c];
}

可以使用以下代码测试:

int main() {vector<int> v{0, 8, 10, 6, 3, 7, 2};  //价值vector<int> w{0, 4, 6, 2, 2, 5, 1};  //重量int c = 12;  //最大承载重量cout << getLargestValue_3( v, w, c ) << endl;return 0;
}

最终答案为24。

【动态规划】01背包问题相关推荐

  1. 动态规划—01背包问题

    原文作者:弗兰克的猫 原文地址:[动态规划]01背包问题 摘要: 01背包问题:n个物品放入容量为c的背包中. 常见解法: 分治法:递归计算,且存在重复计算的bug 自上而下填表法:从大到小使用递归计 ...

  2. 动态规划——0-1背包问题

    文章出处:极客时间<数据结构和算法之美>-作者:王争.该系列文章是本人的学习笔记. 1 0-1背包问题 背包能够承受的总重量一定w,每个物品的总量不同int[] weight表示.怎么放才 ...

  3. 动态规划——01背包问题 看此一篇文章就够了

    本文讲述经典算法--动态规划的 常见问题 01背包  一篇文章带你学会01背包问题,妈妈再也不担心我遇到01背包了!!! 问题描述 有n个物品,它们有各自的体积和价值,现有给定容量m的背包,如何让背包 ...

  4. 动态规划---01背包问题(2种方法)

    一.动态规划 代表一类问题(最优子结构或子问题最优性)的一般解法,是设计方法或者策略,不是具体算法 本质:递推,核心是找到状态转移的方式,写出dp方程. 解决问题:交叉,重叠子问题(最优子问题) 形式 ...

  5. 动态规划01背包问题入门学习,详细笔记,推荐阅读

    问题描述: 给定N种物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得转入背包的物品的总价值为最大?? 在选择物品的时候,对每种物品i只有两种选择, ...

  6. python实现动态规划0-1背包问题

    一.动态规划算法介绍 动态规划算法通常用于求解具有某种最优性质的问题.在这类问题中,可能会有许多可行解.每一个解都对应于一个值,我们希望找到具有最优值的解.动态规划算法与分治法类似,其基本思想也是将待 ...

  7. 详解动态规划01背包问题--JavaScript实现

    对其他动态规划问题感兴趣的,也可以查看 详解动态规划最少硬币找零问题--JavaScript实现 详解动态规划最长公共子序列--JavaScript实现 一开始在接触动态规划的时候,可能会云里雾里,似 ...

  8. 动态规划--01背包问题详解

    代码随想录day42和day43 动态规划 模块01背包问题 "即使到不了远方,心中也要有远方的模样." 文章目录 1. 01背包理论基础 1.1什么是背包问题 1.2二维dp数组 ...

  9. 1.动态规划--01背包问题

    动态规划 DP问题思考时候分成两大部分考虑 1. 状态表示 f(i,j) (1) 集合:(所有选法的集合) 所有选法 条件: 1.从前i个物品中选 2. 总体积m<=j (2) 属性 最大值.最 ...

  10. 动态规划-01背包问题

    大佬整理的理解链接:(建议先看一遍自行理解DP思想再去看代码) 动态规划之01背包问题 - kkbill - 博客园01背包问题 问题描述: 给定 n 件物品,物品的重量为 w[i],物品的价值为 c ...

最新文章

  1. MySQL Workbench的使用教程 (初级入门版)
  2. GATK之VariantAnnotator
  3. 九零后女孩币圈变形记
  4. Android remote debug 打开手机应用里的网页却显示空白
  5. OO思想(只留做自己看理解)
  6. AR Camera开发记录(一) -- Rajawali的使用
  7. PHP100视频教程解压密码[连载结束]
  8. oracle exadata咨询,Oracle Exadata专家手册
  9. matlab常用函数解释,MATLAB常用函数总结
  10. 暴走英雄坛服务器维护到什么时候,暴走英雄坛在4月25日更新了什么 最新维护内容介绍...
  11. css加密数据 图片解析破解
  12. 用Latex排版论文(2)《自动化学报》Latex模版使用时需要注意的问题
  13. springboot整合thymeleaf启动错误
  14. 2020中国游戏公司财报分析《笔记》
  15. 基于Python语言的PUBG游戏数据可视化分析系统
  16. Ocaml——Let
  17. 2012百度校园招聘笔试试题
  18. Windows 搭建 React Native
  19. 什么是符号(Symbols)?
  20. 红外热像仪方便研发合理布局

热门文章

  1. JAVASCRIPT常用20种小技巧汇总
  2. css常用属性总结:颜色和单位
  3. [转帖]真TM长的:SQL Server 2008存储结构——GAM和SGAM、PFS结构、IAM结构、DCMBCM
  4. acdream 1409 Musical 状压DP
  5. YTU 2903: A--A Repeating Characters
  6. 计算机博士英语复试题目,博士复试自我介绍中英文双语解读
  7. mocha 测试 mysql_e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDrive
  8. 公众平台模板消息所在行业_第三方工具微信公众号模板消息群发如何操作?
  9. matlab中求积函数,MATLAB软件及高斯勒让德求积公式MATLAB软件及高斯勒让德求积公式.doc...
  10. java接口开发_如果你想学好Java,这些你需要了解