动态规划学习-【0-1背包问题】

动态规划之0-1背包问题(详解+分析+原码) 本篇文章将介绍算法专题之动态规划中的背包问题,更准确的说是背包问题中最简单的一种类型,即0-1背包问题,就是给你一定容量的背包和若干物品,每种物品只能选一次,告诉你每件物品的价值和体积,求背包里面物品的最大总价值。 阅读详情

题目描述:

问题:0-1背包问题

描述:有一个背包,它的容量为C(Capacity),现在有n种不同的物品编号分别为0...n-1,其中每一件物品的重量为w(i),价值为v(i)。问可以向这个背包中盛放哪些物品,使得在不超过背包容量的基础上,物品的总价值最大。

解题思路:

(1)暴力解法:

每一件物品都可以放进背包,也可以不放进背包,有2^{n}种情况。我们再从这2^{n}种情形中选出总价值最大的物品,时间复杂度为O(2^{n}*n)。

(2)贪心算法解法:

贪心算法:用物品的价值除以重量得到单位物品的价值。贪心算法就是优先放入平均价值最高的物品。

第0件物品的单位价值为6,第1件物品的单位价值为5,第2件物品的单位价值为4。我们首先放单位价值最高的物品0号,它的重量是1。接着放入单位价值次大的物品1号,它的重量是2,。背包中还能容下2个重量,由于编号为2的物品重量是3,所以不能放入到背包中。所以贪心算法得到的背包中最多能容纳16价值的物品。

很明显,对于这个问题,我们只放入编号为1和2的物品,总价值是最大的。与贪心算法恰恰相反的是,我们刚好放弃了单位价值最大的编号为0的商品。所以这个例子证明,贪心算法是无法解决这样的问题。

(3)动态规划解法:

动态规划解题思路:

1. 状态转移方程:

之前接触到的动态规划题目涉及到的状态都可以用一个变量(或者参数)解决问题。通常问题中含有的参数,决定了问题需要满足的约束条件。对于当前的背包问题,也是求一个最优解的问题。对于这个问题,我们两个约束条件,第一个约束条件是在n个物体里选择,第二个约束条件是选定的容量要小于等于给定的C值。求解价值最大的函数设为F(n, C),F函数传入两个参数n和C。F(n,C)函数的定义是:考虑将n个物品放进容器为C的背包,使得价值最大。

我们知道问题的状态转移方程之后,可以使用自顶向下的方式(递归法)解决这个问题;也可以对递归法进行优化使用记忆化搜索的方式解决这个问题;最后我们写出自底向上的动态规划解法。

1)递归方法实现

class Solution:

    def knapsack01(self, w, v, C):
        return self.bestValue(w, v, len(w)-1, C)

    def bestValue(self, w, v, index, C):

        if index < 0 or C <= 0:
            return 0

        res = self.bestValue(w, v, index - 1, C)

        if C >= w[index]:
            res = max(res, v[index] + self.bestValue(w, v, index - 1, C - w[index]))

        return  res

solution = Solution()
w = [1, 2, 3]
v = [6, 10, 12]
print(solution.knapsack01(w, v, 5))

2)记忆化搜索方法实现

class Solution:

    def __init__(self):
        self.memo = []

    def knapsack01(self, w, v, C):
        self.memo = [ [-1 for i in range(C+1)] for _ in range(len(w))]
        return self.bestValue(w, v, len(w)-1, C)

    def bestValue(self, w, v, index, C):

        if index < 0 or C <= 0:
            return 0

        if self.memo[index][C] != -1:
            return self.memo[index][C]

        res = self.bestValue(w, v, index - 1, C)

        if C >= w[index]:
            res = max(res, v[index] + self.bestValue(w, v, index - 1, C - w[index]))

        self.memo[index][C] = res

        return self.memo[index][C]

solution = Solution()
w = [1, 2, 3]
v = [6, 10, 12]
print(solution.knapsack01(w, v, 5))

上面代码不能体现出Python语言的简洁性,代码优化后为:

class Solution:

    def knapsack01(self, w, v, C):
        memo = [ [-1 for i in range(C+1)] for _ in range(len(w))]

        def bestValue(w, v, index, C):

            if index < 0 or C <= 0:
                return 0

            if memo[index][C] != -1:
                return memo[index][C]

            res = bestValue(w, v, index - 1, C)

            if C >= w[index]:
                res = max(res, v[index] + bestValue(w, v, index - 1, C - w[index]))

            memo[index][C] = res

            return memo[index][C]

        return bestValue(w, v, len(w)-1, C)

solution = Solution()
w = [1, 2, 3]
v = [6, 10, 12]
print(solution.knapsack01(w, v, 5))

3)动态规划方法实现

根据上面分析出来的状态转移方程,我们可以做出如下表格:

根据上面表格,用Python实现动态规划解法如下: 

class Solution:

    def knapsack01(self, w, v, C):

        assert len(w) == len(v)

        if len(w) == 0 or len(v)== 0:
            return 0

        memo = [[0 for i in range(C + 1)] for _ in range(len(w))]

        for i in range(C + 1):
            memo[0][i] = v[0] if i >= w[0] else 0

        for i in range(len(v)):
            for j in range(C + 1):
                memo[i][j] = memo[i - 1][j]
                if j >= w[i]:
                    memo[i][j] = max(memo[i][j], v[i] + memo[i - 1][j - w[i]])

        return memo[-1][-1]

solution = Solution()
w = [1, 2, 3]
v = [6, 10, 12]
print(solution.knapsack01(w, v, 5))

时间复杂度为:O(n * C)

空间复杂度为:O(n * C)

0-1背包问题(动态规划,含可运行代码) 一、0-1背包问题的数学模型 1、U={u1,u2,...,un}是一个准备放入容量为C的背包中的n项物品的集合。 2、对于1≤j≤n,令wj和vj分别为第j项物品的体积和价值,这里C,wj,vj和j都是正整数。 3、要找出一个子集合SU,使得最大。 4、约束条件是:。 二、0-1背包问题求解方法 一)穷举法 不推荐使用此法解决背包问题,算法复杂度为O()。 二)动态规划... 阅读详情

相关推荐

算法设计 - 01背包问题的状态转移方程优化,以及完全背包问题

算法设计 - 01背包问题的状态转移方程优化,以及完全背包问题

优快云 5546

0-1背包问题:动态规划的经典应用

背包问题是在给定一组物品和一个背包容量的情况下,如何选择物品放入背包,以使得放入背包的物品总价值最大化。0-1背包问题是背包问题的一个经典变种,其中每个物品要么完全放入背包,要么完全不放入,不能切割物品。在本文中,我们将探讨如何使用动态规划算法解决0-1背包问题,并提供Java实现示例。0-1背包问题是背包问题的一种变种,其特点是每个物品要么完全放入背包,要么完全不放入,不能切割物品。具体而言,我们有一组物品,每个物品有自己的重量和价值,以及一个背包的容量限制。

Java领域 1万+

算法学习014 0-1背包问题 c++动态规划算法实现 中小学算法思维学习 信奥算法解析

C++0-1背包 一、题目要求 1、编程实现 有 N件物品和一个容量为 M的背包,每件物品有各自的价值且只能被选择一次,要求在有限的背包容量下,装入的物品总价值最大。 2、输入输出 输入描述:第一行输入两个整数,分别表示N和M,中间空格隔开 第二行输入N个整数,表示每件物品需要的空间(vi) 第三行输入N个整数,表示每件物品的价值(wi) 输出描述:只有一行,一个整数,即最大的价值总和

青少年编程学习指导 878

01背包问题

一、0-1背包问题的状态转移方程 设F(n, C)考虑将n个物品放进容量为C的背包中,使得价值最大。 对于F(i, c)有两种选择: (1)对于第i个物品不需要放入背包中,则该问题就变成F(i - 1, c) (2)对于第i个物品需要放入背包中,则该问题就变成F(i - 1, c - w(i)) + v(i) 在二种选择选择最大值就为01背包的解,为: F(i, c) = max(F(i - 1, c), F(i - 1, c - w(i)) + v(i)) 时间复杂度:O(n * c);空间复杂度:O

sinat_35180198的博客 1053

视频编解码——视频编解码器工作原理

目录什么是视频编解码器为什么需要视屏编解码器视频编码器与数字视频容器时评编码器的历史 什么是视频编解码器 简单来说就是用于压缩或解压数字视频的软件或硬件 编码是信息从一种形式或格式转换为另一种形式的过程,解码是编码的反向。 适用于视频 编码是将视频、音频的原始格式的文件通过压缩技术转换成另一种格式(视频如h.264,h.265,m-jpeg等)。 解码是编码的反向过程。应用中,一般是将h.264,h.265格式数据解码成如YUV格式裸流交给显示器显示。 为什么需要视屏编解码器 需要在有限的带宽或存储空间

路人coder 1万+

网络基础(二):数制转换与分类编址的IPv4地址

本文介绍数制转换、IP地址、分类编址的IPv4地址,希望对你有帮助!

十七拾的博客 1055

动态规划背包问题学习笔记:目标和(0-1背包),零钱兑换(完全背包)

ps:笔记和代码按本人理解整理,重思路。

学习记录 1531

内网开发必备:5分钟搞定WSL2离线安装(含Ubuntu迁移避坑指南)

本文详细介绍了在内网环境下快速完成WSL2离线安装的完整流程,包括系统兼容性检查、Linux内核更新包安装以及Ubuntu镜像的离线部署。特别针对外网Ubuntu环境迁移至内网时的用户权限、系统路径等常见问题提供了实用解决方案,帮助开发者高效搭建Linux开发环境。

weixin_29255731的博客 402

动态规划学习 0-1背包问题,学习笔记

** 动态规划学习 0-1背包问题,学习笔记 ** 最近在学习动态规划,对于一个问题解决的大致思路如下:根据已知问题分析出其状态转移方程 然后根据该方程先使用递归的暴力解法来解解决问题,由于该方式会产生大量的重叠子问题,于是在递归的基础上衍生出了一种记忆化搜索的方式,该方式有效地减少了递归函数的调用。 以上两种方式都是由一种自顶向下的方式进行思考,而动态规划问题则反其道而行之,通过自底向上...

qq_29422755的博客 392

ego-planner启动参数深度解析:从配置到实战避障应用

本文深入解析EGO-Planner启动参数的配置与实战应用,重点探讨无人机自主导航中的避障性能优化。通过环境感知、运动约束和算法控制三类参数的详细说明,结合ROS和RViz工具,提供从基础配置到高级调优的完整指南,帮助开发者提升无人机在复杂场景下的规划效率和安全性。

rum55的博客 246

Android Framework WMS全面概述和知识要点

WindowManagerService 类是整个 WMS 的核心大脑,处于系统服务层,负责协调和管理所有与窗口相关的操作。它在 Android 系统架构中起到承上启下的关键作用,向上对接应用层的窗口请求,向下与 SurfaceFlinger 等底层组件交互,确保窗口能够正确地在屏幕上显示和管理。

大模型大数据攻城狮的专栏 1794

动态规划学习-【0-1背包问题的优化和变种】

0-1背包问题的基本描述和解题算法请看: 动态规划学习-【0-1背包问题】 上面这篇文章我们已经得出0-1背包问题的状态转移方程: F(n, C)考虑将n个物品放进容量为C的背包,使得价值最大: F(i, C) = max( F(i - 1, C), v(i) + F(i - 1, C - w(i))) 1. 空间复杂度为:O(2 * C) 根据状态转移方程,我们可以分析出来,第i...

Microstrong 3160

从后端角度浅谈抗辐射设计----三模冗余(TMR)

三模冗余设计(TMR),是最常用的一种容错技术,三个模块采取相同的操作,以多数相同的输出作为表决系统的正确输出,即3取2,因为三个模块是相互独立的,而其中两个模块同时出错的概率是极小的,因此便可保证系统输出的可信度。然而这个设计也会存在面积浪费,功耗的增加,而且由于是冗余的设计,在后续进行综合或者pr的时候会被工具优化,因此需要对模块进行don’t touch设置;通过增值表得到,逻辑关系表达式为:Q=(Q1&Q2)|(Q1&Q3)|(Q2&Q3),通过工艺库的stdcell进行搭建,得到如下电路。

芯冰乐 327

动态规划算法学习三:0-1背包问题

动态规划算法学习三:0-1背包问题

冯安晨 3348

热力学仿真软件:SimScale_(1).SimScale入门与基础操作

导航栏:位于页面顶部,包含项目管理、仿真设置、结果分析等主要功能。项目列表:展示用户创建的所有项目。工作区:用于进行具体的操作,如几何建模、网格划分、边界条件设置等。控制台:显示操作日志和仿真进度。网格划分是将几何模型离散化为一系列小单元的过程,这些单元用于求解热力学方程。SimScale提供了多种网格划分方法,包括结构化网格和非结构化网格。SimScale提供了丰富的API接口,用户可以通过编程语言进行二次开发,实现自动化仿真和结果分析。项目管理:创建、删除和管理项目。几何建模:创建、导入和修复几何模型。

kkchenjj的博客 1867

基于动态规划的0-1背包问题学习

动态规划是一种解决多阶段决策过程最优化问题的数学方法。其基本思想是将问题分解成若干个子问题,通过求解子问题的最优解来推导出原问题的最优解。具体而言,动态规划方法可以分为两个步骤:定义状态:将原问题转化为某一阶段的子问题,并记录下该子问题的最优解。状态转移方程:通过对每个子问题的最优解进行组合,得到原问题的最优解。在定义状态时,需要明确每个状态所代表的含义和与其他状态之间的关系;在构造状态转移方程时,需要根据前一个状态推出当前状态,从而不断递推到最终状态,得到最优解。

昊月光华的博客 262

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

学习用动态规划算法来解决0-1背包问题(java实现)

0-1背包问题(动态规划) 大致目录0-1背包问题(动态规划)前言一、动态规划算法是什么?二、动态规划算法基本思想三、解决0-1背包问题总结 前言 提示·: 在算法的学习过程中我们会遇到各种各样的算法思想,其中有一个动态规划算法,它可以认为是一种多阶段决策问题,而所谓的多阶段决策问题也就是指活动过程可按时间或空间顺序分解成若干相互独立、相互联系的阶段,而本文的问题0-1背包问题就是基于动态规划而去实现的一个日常问题 一、动态规划算法是什么? 首先要讲动态规划问题之前我们可以来理解一下一个挖金矿问题,正是

九墨、的博客 1868

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

动态规划学习笔记之0-1背包问题

课堂上老师是从找零问题(即给一些不同面值种类的钱币,用户输入一定金额,要求输出用最少的个数的钱币组合)开始引入的贪心算法,分治思想以及动态规划方法。日常生活中我们也许没有注意到,自己在处理找零问题时总是采用的是贪心算法,每次都从最大面值的钱币开始,直至剩余值小于最大面值,才开始选取更小一点的面值,这样的方法简单,复杂度低,但是不一定能得到全局最优的结果。而分治思想就是把一个复杂的大问题分解成几个完

mantofast的专栏 435

数据结构 : 动态规划学习四 | 0-1背包问题

动态规划学习四 | 0-1背包问题 问题描述 有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 举例 number=4,capacity=8 i 1 2 3 4 w(体积) 2 3 4 5 v(价值) 3 4 5 6 过程 这是最基本的背包问题. 特点: 每种物体仅有一件. 可以选择放或者不放. 用子问题定义状...

【黑键】 365

算法学习-动态规划-0-1背包问题

对于一个背包问题的最优解,我们在这里减去其中的一个物品i,那么背包剩下的物品是不是当背包容量为C-w[i]时,对于(1,2,3...i-1)这些物品的最优解。如图所示,是一个经典的0-1背包问题,对这种问题,网上有很多其他的求解方法,我在这里使用动态规划的思想来求解。要注意,这里的dp数组都是0开始的,所以v,w数组坐标都是1开始,0号坐标填0即可。其中i表示,可以选择0到i号物品进行求解问题,j表示背包容量大小。接下来我们需要寻找递推关系,这也是该问题中最困难的一步。

weixin_45629747的博客 248

【一周编程学习】--7.DP动态规划 0-1背包问题

1.01背包问题 0-1 背包问题:给定 n 种物品和一个容量为 V的背包,物品 i 的重量是 wi,其价值为 vi 。 问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大? 首先回顾动态规划的内容,DP与分治区别在于划分的子问题是有重叠的,解过程中对于重叠的部分只要求解一次,记录下结果,其他子问题直接使用即可,减少了重复计算过程。 最优子结构性质:最优解包含了其子问题的最优解...

wxq_1993的博客 760

从0-1背包问题学习回溯法、分支界限法、动态规划

一、0-1背包问题的描述 下面将使用回溯法、分支界限法、动态规划法来分析和解决此问题。 二、算法分析以及代码 1、回溯法 (1)算法步骤 2、分支界限法 3、动态规划

主要记录嵌入式学习与开发过程。 2601

算法学习打卡day42|动态规划:0 - 1背包问题

经典0-1背包问题:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

weixin_45124219的博客 262

算法学习笔记9——蛮力法和动态规划法求解0/1背包问题

完整代码: #include<iostream> #include <windows.h> #include<iomanip> using namespace std; int c; //背包的容量 int bag_values=0;//背包(装入)的价值 初始化为0 int goods_num; //货物的数量 int maxValue = -1; //定义最大的价值 int calc_arrangement(); //函数 在后面实现 /*结构体 物

weixin_44342332的博客 1227

背包问题 贪心算法_算法学习之从背包(贪心策略)到0-1背包(动态规划)

(本文长度:3958个字;预计阅读时间:10分钟)背包(贪心策略)背包问题本质上即转载问题,通常是在一定条件限制范围内要求我们寻求最佳的装载方式获取最佳的利益。所以普通的背包问题我们可以通过贪心算法来寻求最佳收益。我们通过一个大家都耳熟能详的故事来说明贪心算法在普通背包问题中的应用。我们要讲的就是“阿里巴巴和四十大盗”的故事。有一天,阿里巴巴赶着毛驴上山砍柴。下山的时候,远远看见一股尘烟,弥漫着直...

weixin_30118919的博客 1140
上一篇: 【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown
下一篇: 动态规划学习-【0-1背包问题的优化和变种】
Microstrong0305
Microstrong0305 领域专家: 算法与数据结构技术领域 领域专家: 算法与数据结构技术领域
博客等级 码龄12年 6405粉丝 312原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值