dp 动态规划 01背包问题 Python

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

参考学习网址:
https://www.bilibili.com/video/av33930433?from=search&seid=10637513335818789097

https://www.cnblogs.com/anzhengyu/p/11408466.html

问题描述:
给定 n 件物品,物品的重量为 w[i],物品的价值为 v[i]。现挑选物品放入背包中,假定背包能承受的最大重量为 c,问应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?

思路:
刚开始接触到这个题目的想法是将单位价值最大次大…的几个物品依次装入背包(对单位价值的物品进行排序,从大到小),如果这个装不下就判断下一个是否能装入,直到判断完所有的物品,从而使背包中价值最大。可是这个做法只能通过一些测试,大部分测试通过不了。其实,这是一种贪心算法的思想,这种做法并不能保证背包最终被装满,这些剩余的空间就造成了价值的降低。贪心算法是一种只考虑局部最优的方法,而不是整体最优的方法,所以这个算法思想不是对所有问题都能求得整体最优解就比如这道01背包。

所以这里使用动态规划的思想,即不做重复运算,依次取出一件物品装入容量为1到c的背包,最终得到容量为c时能装入物品价值最大为多少。

我们只用考虑两种情况,装入和不装入。
在这里插入图片描述

这里dp[i][j]表示只看前i个物品,背包体积为j的情况下,总价值最大是多少。

不装入:如果在背包体积为j的情况下,不装入第i个物品,那么dp[i][j]就取之前背包体积为j的情况下,装入第i-1个物品时的最大价值,即dp[i-1][j]。
状态转移公式为:dp[i][j]=dp[i-1][j]

装入:在背包体积为j的情况下,如果装入第i个物品就需要与同背包体积时装入i-1个物品的最大价值做对比取最大值填入dp[i][j]。选取第i个物品时,总价值为装入的物品i的价值+背包还剩体积的最大价值。
状态转移公式为:dp[i-1][j-v[i-1]]+w[i-1] (遍历物品次数从1开始,价值体积索引-1)

n, c = map(int, input().split())
v_w = []
for i in range(n):v_w.append(list(map(int, input().split())))dp = [[0 for i in range(c+1)] for j in range(n+1)]for i in range(1, n+1):for j in range(1, c+1):dp[i][j] = dp[i-1][j]if j >= v_w[i-1][0]:dp[i][j] = max(dp[i][j], dp[i-1][j-v_w[i-1][0]]+v_w[i-1][1])print(dp[-1][-1])

以上代码就可以得到最优的01背包最大价值解,但是我们发现dp是用二维列表来存储最大价值,但我们只要背包容量为c时所能装的物品最大价值,这样就会造成很大的内存资源消耗。所以我们能不能将二维列表改为一维列表来存储最大价值呢?

通过上面的二维代码,可以发现dp[i]只与dp[i-1]有关。所以我们只需要让dp来存储上一次(选取物品i-1时)的最大价值。

由于在能装入的情况下,背包有剩余空间 (i-1),我们需要i-1体积时的最大价值,所以不能正向改变dp中的最大价值,这时候就需要倒着改变dp中的最大价值。

在这里插入图片描述

dp[i]表示背包容量为i时,选取多少物品得到的总价值最大是多少。

不装入:dp[i]=dp[i],在代码中可以省略

装入:和之前二维类似,dp[j-v[i-1]]+w[i-1]

n, c = map(int, input().split())
v_w = []
for i in range(n):v_w.append(list(map(int, input().split())))dp = [0 for i in range(c+1)]for i in range(n):for j in range(c, -1, -1):if j >= v_w[i][0]:dp[j] = max(dp[j], dp[j - v_w[i][0]] + v_w[i][1])print(dp[-1])

运行结果:
在这里插入图片描述
上面为二维运行结果,下面为一维运行结果。可以看出运行内存和时间均得到了优化。

运行测试网址:https://www.dotcpp.com/oj/problem1924.html

欢迎大家采纳和指正!!!
如果大家有更优的解法,欢迎在评论区留言。


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

相关文章

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

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

算法 动态规划 01背包问题

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

【动态规划】01背包问题

👨‍🎓作者简介:一位喜欢写作,计科专业大二菜鸟 🏡个人主页:starry陆离 🕒首发日期:2022年5月16日星期一 🌌上期文章:【动态规划】最长上升子序列 &#x1f4…

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

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

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

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

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

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

java事务和分布式事务详解

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

JAVA事务配置总结

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

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

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

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

Transactional注解的触发,只回滚RuntimeException和Error异常,默认不回滚非RuntimeException异常 解决方法: 1.方法前添加注解(基础的 Transactional注解:只能拦截RuntimeException和Error异常) Transa…

java中事务

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

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

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

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

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

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

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

Java 事务的传播性(Transactional)

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

Java 事务应用

一, 事务的一些基础知识简单回顾一下,讲的不是很深入,网上博客很多。 1,关于事务的四大特性:原子性、隔离性、一致性、持久性 本文不再赘述; 2,事务的隔离级别:读未提交,…

Java事务管理

事务的ACID属性:原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily) ACID 特性 A(原子性)事务的原子操作单元,对数据的修改,要么全部执行,要么全部不执行&#x…

java 事务级别_java事务隔离级别

事务隔离级别是由数据库系统实现的。 Java事务 1) 说到事务,不得不提的就是ACID特性,再次回顾: 原子性(atomicity):组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分。 一致性(consistency)&#xff1a…

Java中使用事务(注解实现)

Java中使用事务(注解实现) 事务的介绍 描述: 对于一个功能实现或者业务流程,要么全做,要么全不做! 特性: ACID A - 原子性:执行的最小单位,要么全做,要么全…

JAVA的事务

要先知道什么是java中的事务? 事务: 一般是指要做的或所做的事情.专业术语是这样说的: 就是代码逻辑上的一组操作,这些操作要么全部成功,要么全部失败!举一个现实生活当中的例子: 1张三账上有2000元,李四账号也有2000元。张三要向李四转账1000元,正常来…