# 二维dp数组,01背包

1.确定dp数组以及下标的含义

dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

2. 

gpt 解决我的困惑

3. 

另外:

当 j < weight[0]的时候,dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。

当j >= weight[0]时,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品。

所以初始化总共有两部分(第一列,第一行)

其他格子值无所谓,反正每个格子是通过左上得出来

4. 遍历顺序 也很重要。会是有的题目的难点。

本题两层for loop 物品套背包容量或者背包容量套物品都可以,因为都是往右下走就行了

随想录写的是一个从0开始一个从1开始,但是我觉得 i j 都从1开始就行

5. 举例推导dp数组

在格子里自己推导一遍看看对不对

测试代码(用随想录的按自己偏好修改了一点)

void test_2d_bag_problem1(vector<int> &weight, vector<int> &value, int &bagweight) {// 二维数组+初始化1vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));// 初始化2for (int j = weight[0]; j <= bagweight; j++) {dp[0][j] = value[0];}for(int i = 1; i < weight.size(); i++) { // 遍历物品for(int j = 1; j <= bagweight; j++) { // 遍历背包容量if (j < weight[i]) dp[i][j] = dp[i - 1][j];else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);}}cout << dp[weight.size() - 1][bagweight] << endl;
}int main() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagweight = 4;test_2d_bag_problem1(weight,value,bagweight);
}

# 一维滚动dp数组,01背包

 依然是两层for loop, ij都要有,但是只有一层数组了

! 一维数组遍历顺序只能物品(外层)套背包容量,因为我们必须一行行算出结果后下一行继续用

! 一维数组遍历顺序 背包容量 只能 倒序,因为要保证每个物品只用一次,具体理解:

二维每次更新要看斜上方一个值(还是原来的没被覆盖),一维每次更新对应的只能看同行前面某个值,但是如果从前往后已经被这一行的一种新的情况覆盖了。但是如果从后往前的话, 用的dp[j - weight[i]]还是之前那行的

void test_1d_bag_problem1(vector<int> &weight, vector<int> &value, int &bagweight) {// 二维数组+初始化1vector<int> dp(bagweight + 1, 0);// 初始化2for (int j = weight[0]; j <= bagweight; j++) {dp[j] = value[0];}for(int i = 0; i < weight.size(); i++) { // 遍历物品for(int j = bagweight; j >= weight[i]; j--) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}}//for(int j = 1; j <= bagweight; j++) { //if (j >= weight[i])//原来是这样的,但是现在因为倒过来,不需要了,只用决定终止的点是weight[i]就行cout << dp[bagweight] << endl;
}int main() {vector<int> weight = {1, 3, 4};vector<int> value = {15, 20, 30};int bagweight = 4;test_1d_bag_problem1(weight,value,bagweight);
}

面试的问法:

#416. 分割等和子集 

自己没想出来(快想出来了,j的值已经确定了是从0,1,逐渐到sum)

随想录思路:

1. 需要一个subset和是sum/2 (我居然没想出来这个),我一直在想两个subset之和相减为0

背包的体积为sum / 2,j 就是 从 0,1 逐渐到sum

2. 背包中每一个元素是不可重复放入。(01背包)

3. 关键:"每一个元素的数值既是重量,也是价值” 作为重量的话,是用来限制不能超过sum/2 ,做为价值是我们希望他的和尽可能大,以至于到达sum/2。

4. 关键:背包如果正好装满,说明找到了总和为 sum / 2 的子集。

不能装满的情况也是有的:比如 1 5 11 5 ,这个list ,当 j =7 时(因为我们要一直连续过去,所以才会出现这个值)最多1+5只能6,所以就是不能装满

求和也可以用库函数:int sum = accumulate(nums.begin(), nums.end(), 0);

bool canPartition(vector<int>& nums) {int sum = 0;for (int &ele:nums) sum+=ele;// 也可以使用库函数一步求和// int sum = accumulate(nums.begin(), nums.end(), 0);if (sum % 2 == 1) return false;int target = sum / 2;vector<int> dp(target+1, 0);for(int j=nums[0];j<=target;j++) dp[j]=nums[0];// 开始 一维01背包for(int i = 1; i < nums.size(); i++) {for(int j = target; j >= nums[i]; j--) { dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);}}// 集合中的元素正好可以凑成总和targetif (dp[target] == target) return true;return false;}

觉得自己文章摘要总结的很好:

二维01背包:dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])
一维01背包:只能物品外层,j=bagweight;j>=weight[i];j-- 
416. 分割等和子集 :正好装满sum/2, nums[i] 同时是weight和value

代码随想录算法训练营第42天 | 动态规划 part04 ● 背包问题二维● 背包问题滚动数组 一维 ● 416. 分割等和子集相关推荐

  1. _42LeetCode代码随想录算法训练营第四十二天-动态规划 | 121.买卖股票的最佳时机、122.买卖股票的最佳时机II

    _42LeetCode代码随想录算法训练营第四十二天-动态规划 | 121.买卖股票的最佳时机.122.买卖股票的最佳时机II 题目列表 121.买卖股票的最佳时机 122.买卖股票的最佳时机II 1 ...

  2. 代码随想录算法训练营day42 | 01背包问题,你该了解这些!,01背包问题,你该了解这些! 滚动数组 , 416. 分割等和子集

    代码随想录算法训练营day42 | 背包理论基础,背包理论基础(滚动数组), 416. 分割等和子集 1.01背包理论基础 背包问题概述 01背包 二维dp数组01背包案例 2.01背包理论基础(滚动 ...

  3. 代码随想录算法训练营第46天 | 动态规划 part08 ● 139.单词拆分 ● 关于多重背包 ● 背包问题总结篇

    #139 单词拆分 没做出来.我原来是把string放到dp里,不对,这种做法永远都不对.他问的是什么(能不能构成,true,false)就要放到dp里 (大部分题是这样)下面是不对的思路: 正确co ...

  4. 代码随想录算法训练营第四十二天-动态规划4|● 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集

    今天只有1道题,属于动态规划的01背包问题的应用.首先理解一下动态规划的01背包问题.推荐一个视频,动态规划DP0-1背包,这是我认为讲得最为通透的.很多讲解动态背包问题的,一上来就画二维表格,遍历背 ...

  5. 代码随想录算法训练营第45天动态规划 背包基础 1 2、 416. 分割等和子集

    文章目录 01背包基础 (二维数组) 思路 递推公式 初始化 遍历顺序 一维dp数组(滚动数组) 一维数组的递推公式 遍历顺序 LeetCode 416. 分割等和子集 思路 总结 01背包基础 (二 ...

  6. 代码随想录算法训练营第四十二天 | 01背包问题,你该了解这些、01背包问题,你该了解这些 滚动数组、 416. 分割等和子集

    打卡第42天,搞搞01背包. 今日任务 01背包问题,你该了解这些! 01背包问题,你该了解这些! 滚动数组 416.分割等和子集 背包问题1.0 :0-1 背包 有n件物品和一个最多能背重量为w 的 ...

  7. 代码随想录42——动态规划:0-1背包理论基础、0-1背包滚动数组、416分割等和子集

    文章目录 1.0-1背包理论基础 1.1.概述 1.2.0-1背包 1.3.二维dp数组01背包--动规五部曲 1.4.完整测试代码 2.0-1背包滚动数组 2.1.一维滚动数组 2.2.一维dp数组 ...

  8. _28LeetCode代码随想录算法训练营第二十八天-贪心算法 | 122.买卖股票的最佳时机II 、55.跳跃游戏、45.跳跃游戏II

    _28LeetCode代码随想录算法训练营第二十八天-贪心算法 | 122.买卖股票的最佳时机II .55.跳跃游戏.45.跳跃游戏II 题目列表 122.买卖股票的最佳时机II 55.跳跃游戏 45 ...

  9. _32LeetCode代码随想录算法训练营第三十二天-贪心算法 | 738.单调递增的数字 、714.买卖股票的最佳时机含手续费、968.监控二叉树

    _32LeetCode代码随想录算法训练营第三十二天-贪心算法 | 738.单调递增的数字 .714.买卖股票的最佳时机含手续费.968.监控二叉树 题目列表 738.单调递增的数字 714.买卖股票 ...

最新文章

  1. 计算机内存作图多大合适3d,【2人回答】你好,我想问问电脑256G内存对于学生画图设计够吗?-3D溜溜网...
  2. 复习计算机网络基础 day3---什么是计算机网络:
  3. 【git】 重置文件
  4. pip3 install face_recognition
  5. 基于Smith预估器的PID控制在房间湿度控制
  6. python excel取数 生成报告_python+requests+excel+unittest+ddt接口自动化数据驱动并生成html报告(二)...
  7. [css] 你有使用过css的writing-mode属性吗?说说它有哪些应用场景?
  8. axios发送请求(baseURL有多个的情况)
  9. jfinal项目部署服务器,jfinal undertow项目再集成JDK,一键安装系统服务,让部署再快一点...
  10. Exception in thread main com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport e
  11. 机器人动力学与控制_力控制与位置控制的区别
  12. 【转载】你不得不知道的深度学习网络画图工具
  13. CPU使用率,Blender顶级视频教程,Python,Linux,Stratis,Pidgin等
  14. 成功领导者的20个好习惯
  15. 【算法题目】数组中的逆序对
  16. 【每日算法Day 95】美团笔试题:四面体方案个数
  17. Linux inittab和oracle lsntctl 启动的问题解决办法
  18. 最完美的matlab绘图教程集合
  19. Ansible学习笔记——JINJA2模板的语法及使用(template模块)
  20. 数字字母下划线C语言,【判断题】C语言中的标识符只能由字母、数字和下划线三种字符组成,而且第一个字符只能是字母和下划线。...

热门文章

  1. poj 1904 tarjan强连通分量(给国王的2000个儿子找老婆 )
  2. 【转】jsp 表单form传值
  3. PR第一次培训笔记(新建项目和序列 预设)
  4. 2022-2027年中国摄像模块市场竞争态势及行业投资前景预测报告
  5. git 错误 10054
  6. 青春护航 一下科技韩坤谈对青少年“限制”策略
  7. Java中字符串连接符“+“
  8. ajax提交的表格怎么增加样式,20 个精美的Ajax + CSS 的表格效果_jquery
  9. 邓白氏编码(duns number)申请以及填写方法-苹果开发者申请必用
  10. Termux详细教程!