动态规划——背包问题(01背包问题)

article/2025/10/3 1:49:56

    • 动态规划——背包问题(01背包问题)
      • 01背包问题(求最大价值):
      • 问题优化
      • 01背包问题(求方案数):

动态规划——背包问题(01背包问题)

01背包问题(求最大价值):

有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每个物品只有一样(只能用一次),求解哪些物品放入背包能使价值总和最大?
背包问题可以用二维的动态规划去求解。

  • 对于dp数组的含义理解:dp[i][j]表示从编号0~i的物品中选取物品,装入容量为j的背包中所能得到的最大价值为dp[i][j]。
  • 接下来来考虑dp[i][j]的递推式:dp[i][j]可以由两个方向推出:
    1、本轮不放物品,则本轮价值与从编号0~i - 1的物品中选取物品,装入容量为j的背包中所能得到的最大价值相同,即dp[i][j] = dp[i - 1][j]。
    2、本轮放物品,物品从0~i的物品中挑选,记物品为j(0≤j≤i),则本轮价值为从编号0到i - 1的物品中选取物品装入容量为j - weight[i]的背包价值再加上选取的这个物品的价值(value[i])。
    dp[i][j]应该从两个中取最大的,即dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
    考虑初始化:
    由递推式可以看出后面的状态依赖于前面的状态,所以要初始化第一行以及第一列.。即dp[i][0] = 0,
    dp[0][j] 为只有第一个物品放入背包的价值(如果背包能放下第一个物品的话)。
  • 考虑遍历顺序:
    由递推式可以看出遍历顺序从上到下,从左到右。那么就需要两个for循环。那么就有两个遍历顺序
    1、先遍历背包容量,在遍历物品(即先行后列)。表示将物品依次分别放入背包容量是0至W的背包中,得到最大价值。
    2、先遍历物品,在遍历背包容量(即先列后行)。这表示先固定下来一个容量为j的背包,将所有物品尝试放入,得到最大价值。
    从递推式可以看出dp[i][j]至于左上部分有关,这两种遍历顺序都能保证在dp[i][j]时左上部分已经构建完毕,所以这两种遍历顺序都可以
    在这里插入图片描述
//dp数组初始化
vector<vector<int>> dp(N, vector<int>(W + 1, 0));
for (int j = 0; j <= W + 1; ++j) {if (weight[i] <= W) {dp[0][j] = value[0];}
}//遍历
for (int i = 1; i < N; ++i) {for (int j = 0; j <= W; ++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]);}
}return dp[N - 1][W];

问题优化

二维的递推式为dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]),我们可以看到,下一层的数据是依赖上一层的数据推出的(即dp[i] 可以先把上一层的数据复制下来,再在此基础上进行操作)。由于每一层的数据仅和与自己相邻的上一层的数据相关,我们可以将二维数组压缩成一维数组。
即将 dp[i][j]变成dp[j]

  • dp[j]的含义:背包容量为j的背包可以容纳的物品的最大价值总和为dp[j];
  • 递推关系:
    dp[j]可以由两个方向得出,设本次放的物品为i:
    1、本次不放物品:则dp[j] = dp[j],即背包价值总和不变
    2、本次放物品: 则dp[j] = dp[j - weight[i]] + value[i],即背包容量为j - weight[i]的背包的最大价值总和加上本次放的物品的价值。
    两者取最大,即dp[j] = max(dp[j], dp[j - weight[i]] + value[i])。
  • 遍历顺序:
    一维数组要么从前往后遍历,要么从后往前遍历。如果从前往后遍历,那么后面的必定会用到前面的数据,就会发生重复放置的问题。
    举个例子
    在这里插入图片描述
    dp数组如上,可以看到背包容量为2的背包计算了两次物品1。这是由于计算dp[2]的时候使用了dp[1],而此时dp[1]已经放置了物品1,当dp[2]再次利用物品1计算时就会出现重复。因此遍历顺序必须由后向前,才能保证每个物品只使用一次。也是因此,只能先遍历物品在遍历背包
    初始化
    各个背包一开始没有物品,都为0。
vector<int> dp(W + 1);
for(int i = 0; i < N; ++i){for(int j = W; j >= weight[i]; --j){dp[j] = max(dp[j], dp[j - weight[i]] + value[i])}
}
return dp[W];

01背包问题(求方案数):

有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每个物品只有一样(只能用一次),求解使背包价值最大的物品组合共有几种?
这个与上面的问题主要有如下不同:

  • dp[j]含义:装满背包容量为j的最大价值的物品组合数共dp[j]种。
  • 递推式:
    得到dp[j]的方向:假设本次拿到的物品为i 那么dp[j]就是自己原本的方案数再加上 dp[j - weight[i]]的方案数,即 dp[j] += dp[j - weight[i]]
  • 初始化:
    dp[j]是由前向后推出的,因此要初始化的是dp[0] = 1 :装满容量为0的背包的最大价值的物品组合有一种,就是什么也不装。
vector<int> dp(W + 1);
dp[0] = 1;
for(int i = 0; i < N; ++i){for(int j = W; j >= weight[i]; --j){dp[j] += dp[j - weight[i]];}
}
return dp[W];

http://chatgpt.dhexx.cn/article/nJ1Xxvy3.shtml

相关文章

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

动态规划&#xff1a;关于01背包问题&#xff0c;你该了解这些&#xff01; 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff0c;就够用了&#xff0c;最多可以再来一个多重背包。 如果这几种背包&#xff0c;分不清&#xff0c;我这里画了一个图&…

c++ 动态规划-01背包

动态规划 - 01背包问题 1.使用递归遍历(穷举)求解&#xff1a; 01背包问题&#xff1a;给定 n 种物品和一个重量(容量)(限定条件)为 w 的背包,物品 i 的重量是 wi,其价值为 vi。(每种物品只有一个)问:如何选择装入背包的物品,使得装入背包中的物品的价值最大。 //VC6.0------…

动态规划——01背包问题(C++实现)

题目描述&#xff1a; 解题思路&#xff1a; 整体思路&#xff1a; 利用动态规划&#xff0c;其目的就是将原问题分解成几个子问题&#xff0c;通过求解简单的子问题&#xff0c;把原问题给解决&#xff0c;就比如斐波那契数列方程&#xff1a; f[i]f[i-1]f[i-2]; 动态规划的…

动态规划总结三01背包问题

01背包问题一般是利用动态规划进行解题的&#xff0c;这里通过leetcode1049来讲解01背包的解题思路以及如何对01背包应用题目转换和理清思路 01背包问题&#xff1a; 这里借用学习公众号代码随想录的一张图来说明背包问题的种类 对于面试的话&#xff0c;其实掌握01背包&…

dp 动态规划 01背包问题 Python

参考学习网址&#xff1a; https://www.bilibili.com/video/av33930433?fromsearch&seid10637513335818789097 https://www.cnblogs.com/anzhengyu/p/11408466.html 问题描述&#xff1a; 给定 n 件物品&#xff0c;物品的重量为 w[i]&#xff0c;物品的价值为 v[i]。现…

Python3使用动态规划处理01背包问题

文章目录 视频教程讲解题目介绍题解1&#xff1a;二维列表题解2&#xff1a;一维列表&#xff08;滚动数组&#xff09;延伸阅读 视频教程讲解 【Python算法系列】动态规划2-01背包问题&完全背包问题【Python算法实战】背包问题 题目介绍 原题链接&#xff1a;NC145 01背…

算法 动态规划 01背包问题

01背包 问题分析代码实现从前往后拿&#xff0c;递归实现非递归实现非递归实现&#xff0c;自上向下填充 允接上一文章内容&#xff1a; 算法 动态规划: link. 问题分析 按照普通思维&#xff0c;首先想到应该为贪心算法&#xff0c;也就是计算每个物品重量价值比&#xff0c;…

【动态规划】01背包问题

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位喜欢写作&#xff0c;计科专业大二菜鸟 &#x1f3e1;个人主页&#xff1a;starry陆离 &#x1f552;首发日期&#xff1a;2022年5月16日星期一 &#x1f30c;上期文章&#xff1a;【动态规划】最长上升子序列 &#x1f4…

01背包问题:图表法带你快速理解动态规划解决01背包问题 附C++源码

0-1背包问题 所谓0-1背包问题&#xff0c;也就是给你一个重量为M的背包和n种物品&#xff0c;每种物品有一定的重量和价值&#xff0c;在每种物品均可装入背包1次或不装入&#xff08;不能仅装入物品的一部分&#xff09;且不超过背包载重量的前提下&#xff0c;问你怎样选择物…

动态规划——0/1背包问题(全网最细+图文解析)

✨动态规划——0/1背包问题(全网最细图文解析) 作者介绍: &#x1f393;作者:青花瓷✨ &#x1f440;作者的Gitee:代码仓库 &#x1f4cc;系列文章推荐: ✨1.数据结构与算法—算法篇之动态规划(一) ✨2.【Java刷题特辑第一章】——【点进来花两把游戏的时间学习晚上睡觉都踏实了…

【动态规划】01背包问题(通俗易懂,超基础讲解)

问题描述 有n个物品&#xff0c;它们有各自的体积和价值&#xff0c;现有给定容量的背包&#xff0c;如何让背包里装入的物品具有最大的价值总和&#xff1f; 为方便讲解和理解&#xff0c;下面讲述的例子均先用具体的数字代入&#xff0c;即&#xff1a;eg&#xff1a;numbe…

java事务和分布式事务详解

目录 事务问题 1 Java事务的类型 2 spring事务实现源码分析 事务问题 面试经常会问到分布式锁、分布式事务、SOA 服务化、分布式系统等业务、架构的问题和解决方案&#xff0c;工作中接触的业务方面事关金融&#xff0c;也需要解决一些类似的业务问题&#xff0c;所以总结…

JAVA事务配置总结

JAVA事务配置总结 使用hibernate&#xff1a;1.本地事务动态数据源单sessionFactory 这种情况属于大部分项目配置&#xff0c;在这里不多谈 2.全局事务动态数据源单sessionFactory 数据库分库分表时使用&#xff0c;已解决了不同库中相同名字的表相同ID的数据同时出现在同一…

Java事务回滚问题:抛出异常事务,并返回给前端异常信息

1、背景 修改bug。 之前的开发写的只能单选&#xff0c;所以逻辑都是按照只需要传递一个id值的逻辑写的 现在改为多选时&#xff0c;传递过来的是id数组&#xff0c;所以直接原逻辑的外层加了一个循环&#xff0c;这样原逻辑包括sql就不需要大变动&#xff0c; 但是这样会有个…

java事务中使用try catch 导致事务不回滚的问题

Transactional注解的触发&#xff0c;只回滚RuntimeException和Error异常&#xff0c;默认不回滚非RuntimeException异常 解决方法&#xff1a; 1.方法前添加注解&#xff08;基础的 Transactional注解&#xff1a;只能拦截RuntimeException和Error异常&#xff09; Transa…

java中事务

1.开启事务 事务的四大特性 ACID是原子性&#xff08;atomicity&#xff09;、一致性&#xff08;consistency&#xff09;、隔离性 &#xff08;isolation&#xff09;和持久性&#xff08;durability&#xff09;的缩写。 事务的原子性&#xff1a;事务作为整体执行&#x…

Java事务的ACID属性和四种隔离级别和传播机制

事务的ACID属性 数据库管理系统中事务(transaction)的四个特性&#xff08;分析时根据首字母缩写依次解释&#xff09;&#xff1a;原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&#xff09;、隔离性&#xff08;Isolation&#xff09;、持久性&a…

java回滚失败_java事务回滚失败问题分析

Spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因。 一切还是要从Java的检查型异常和非检查型异常说起。 那么什么是检查型异常什么又是非检查型异常呢? 最简单的判断点有两个: 1…

java中事务特性_java事务的四大特性ACID

前言 对于要把事务在实际中使用好&#xff0c;需要了解事务的特性。 事务的四大特性主要是&#xff1a;原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。 一、事务的四大特性 1.1原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位&a…

Java 事务的传播性(Transactional)

前言 事务的传播性是Spring特有的概念&#xff0c;是基于Spring AOP技术实现的&#xff0c;原本的方法不具备事务的功能&#xff0c;运用Spring AOP的方式动态的增加了事务的功能&#xff0c;来确保数据库的数据的一致性。 只要开启事务的方法发生调用关系就一定存在事务的传…