01背包问题一般是利用动态规划进行解题的,这里通过leetcode1049来讲解01背包的解题思路以及如何对01背包应用题目转换和理清思路


01背包问题:

这里借用学习公众号代码随想录的一张图来说明背包问题的种类

对于面试的话,其实掌握01背包,和完全背包,就够用了,最多可以再来一个多重背包。
首先来看01背包问题的描述
有N件物品和一个最多能被重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
对于这种问题第一印象就是将所有可能的组合遍历出来,每一件物品都有取与不取两种状态,但是这种暴力解法的时间复杂度是O(2^N),对一半题目来说太高了,需要动态规划来降低复杂度。

解题思路:

1.还是从五步骤开始,先是定义数组,确定数组下标含义,在01背包问题中需要迭代更新的有两个变量是物品和重量,我们可以理解为在i个物品j重量的前提下,算出i+1个物品j重量的组合或者i个物品j+1重量的组合,所以数组的定义是dp[i][j]

2.那么可以有两个方向推出来dp[i][j],

由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]
由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值
所以递归公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

同时我们可以从递推公式中看到dp[i]的变化跟dp[i-1]行的变化有关,这种只跟前面一行状态以及当前行已经更新过的状态有关的情况下,可以将数组进行压缩变成一维数组即dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);对于已经被覆盖的数组,递推公式中是完全用不上的。后面为了方便讲解还是继续使用二维数组。
3.数组初始化
关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱。
我们看递推公式中dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])可以看出有两个要初始化的地方dp[i]的状态跟dp[i-1]有关,所有要初始化第0行即物品0号放入各种容量背包中重量大小,但是这里会在遍历中进行更新;还和j - weight[i]有j==weight[i]的情况,所以还要初始化dp[i][0]第0列,当容量为0时候,重量最大上限也是0,所以不用更改。综上所述,需要初始化的地方就是第0行。
首先我们要考虑01背包的条件,每个物品只有一件,不能重复放入,所以必须要从右往左进行倒序遍历,从左往右正序遍历会导致物品放入多次。
初始化递推dp[0][j] = dp[0][j - weight[0]] + value[0];举个反例:0号物品重量为1,如果是正序遍历的话,dp[0][0] = 0,dp[0][1] = 1,那么dp[0][2]=2,就相当于放入两次了。
4.遍历顺序
动态规划是比较看重遍历顺序的,遍历顺序不一样,可能得到的结果会完全不一样。但是在这里哪种遍历顺序都可以,先物品再容量和先容量再物品都可以。

leetcode:1049

有一堆石头,每块石头的重量都是正整数。

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。
官方例子:
输入:[2,7,4,1,8,1]
输出:1
解释:
组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1],
组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1],
组合 2 和 1,得到 1,所以数组转化为 [1,1,1],
组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。

解析
咋一看,这题目跟01背包毫无关系,实际上需要转化思维方式,这是一道01背包的应用题。
首先两两石头进行粉碎,什么情况下能让剩下重量最小就是两块石头重量很接近的时候。那么这道题的解题思路就是将石头分成两堆,让他们重量相近,实际上就是重量少的那堆的重量总和尽量接近于原石头堆stones一半的重量。这就好办了,题目已经转化为背包所容纳的重量为stones/2,物品为石头数组的01背包问题。就可以利用上面01背包的解题思路进行解题了。
代码:

public int lastStoneWeightII(int[] stones) {int sums = 0;for(int i=0;i<stones.length;i++){sums += stones[i];}int sum = sums/2;int[] dp = new int[sum+1];for(int i=0;i<stones.length;i++){for(int j = sum;j>=stones[i];j--){dp[j] = Math.max(dp[j],dp[j-stones[i]]+stones[i]);}}return (sums-dp[sum])-dp[sum];}

动态规划总结三01背包问题相关推荐

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

    动态规划的用法--01背包问题 问题主题:著名的01背包问题 问题描述: 有n个重量和价值分别为wi.vi的物品,现在要从这些物品中选出总重量不超过W的物品,求所有挑选方案中的价值最大值. 限制条件: ...

  2. 【动态规划】P1048 01背包问题:采药

    时间对应容量,用01背包 [动态规划笔记]01背包问题及优化_m0_52043808的博客-CSDN博客 代码: #include<iostream> using namespace st ...

  3. vs2017\vs2019 动态规划算法实现0-1背包问题 C

    这是针对于博客vs2017安装和使用教程(详细)和vs2019安装和使用教程(详细)的动态规划算法实现0-1背包问题的示例 目录 一.问题描述

  4. 动态规划:关于01背包问题 I

    动态规划:关于01背包问题,你该了解这些! 对于面试的话,其实掌握01背包,和完全背包,就够用了,最多可以再来一个多重背包. 如果这几种背包,分不清,我这里画了一个图,如下: 至于背包九讲其其他背包, ...

  5. 动态规划(一):0-1背包问题

    目录 前言 一.原理 1.1 最优子结构性质 1.2 递归关系 二.算法描述 2.1 算法描述 2.2 图解 2.3 构造最优解 三.0−10-10−1 背包问题相关题目 3.1 题目 3.2 源程序 ...

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

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

  7. 【动态规划笔记】01背包问题:leetcode415 分割等和子集

    416. 分割等和子集 问题的另一种表述: 给定一个数组nums,判断是否可以从数组中选出一些数,使得这些数之和等于元素和的一半. 此问题为01背包问题. 该问题的一般描述为:能否选择若干物品,使它们 ...

  8. 【动态规划笔记】01背包问题及优化

    dp[i][j]:在前i件物品中选出若干件,放入容量为j的背包,能获得的最大价值 考虑第i件物品 [拿]  还是  [ 不拿 ] (1)j < c[i] 时,背包容量为j,而第i件物品重量大于j ...

  9. C++动态规划算法之0-1背包问题

    0-1背包问题 题目描述 有 n 件物品, 每件物品有一个价值和一个重量,分别记为: b1,b2, -bn w1,w2, -wn 其中所有的 重量wi 均为整数. 现有一个背包,其最大载重量为W,要求 ...

最新文章

  1. JavaBean组件的基本使用-语法
  2. 问题 B: C语言11.2
  3. linux容器安卓下载,Docker 1.7.0 发布下载,Linux 容器引擎
  4. 编程求以孩子兄弟表示法存储的森林的叶子结点数☆
  5. def __init__(self)是什么意思_一文搞懂什么是Python的metaclass
  6. 数据库设计(一)——数据库设计
  7. 包括淘宝天猫API明细接口
  8. 机器学习_高偏差(High bias)与高方差(High vars)
  9. gin 【日志记录】每天一个日志文件
  10. 学习如逆水行舟,不进则退
  11. 为什么别人总是把你往“坏处想”?浅谈如何更好地与项目团队中的“网友”更好地交流
  12. Linux MD5 programming in C Language
  13. hpc与超级计算机的区别,超级计算和高性能计算(HPC)的综合分析
  14. HTML制作圣诞树来啦
  15. 在华为手机上玩OPPO游戏
  16. 摄像头在线测试_Leez学院| 面部检测 精准可靠 Leez P515 OpenCV工程测试
  17. 利用淘宝指数做产品数据分析
  18. 霍常亮app淘宝客开发视频教程第7节
  19. 【C语言】厘米换算英尺英寸
  20. APK汉化手记 现金流游戏放出

热门文章

  1. 使用for循环打印九九乘法口诀表
  2. 手机触控事件touch
  3. 人脸美颜——飞桨PaddleHub实战
  4. 另辟蹊径,在小程序中获取是否关注公众号
  5. Android实现素材擦除功能
  6. 冒险岛2官网模拟具体教程之二头部的布局以及动态交互实现(详解)(连载)
  7. c语言输入年月的流程图_怎么画C语言万年历的流程图?
  8. 区块链中常用的跨链技术
  9. java WGS-84-火星坐标系-百度坐标系互相转换
  10. 解决layui数据表格中嵌套下拉框显示问题