代码随想录算法训练营第四十五天(动态规划篇)|01背包

news2024/11/14 13:42:11

01背包理论基础

学习资料:代码随想录 (programmercarl.com)

 相关链接:题目页面 (kamacoder.com)

背包题目分类

01背包定义

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

解法

暴力解法

每种物品有两种状态:取或不取,因此可以用回溯法搜索出所有组合,选出价值最大的方案,时间复杂度为o(2^n)。

动态规划

举例:背包重量为4,物品为:

1. dp[i][j]定义

当前背包容量为j时, 从下标为[0, i]的物体中任意取,放到背包中,的最大价值。

    示意图如下:

   

2.递推公式

dp[i][j]可以从两个方向得到:

  • 放物品i: 由dp[i - 1][j - weight[i]]推出,即不放物品i时,容量为[j - weight[i]的背包(要给物品i流出放的重量)时的最大价值加上物品i的价值。
  • 不放物品i:由dp[i-1][j]推出,即容量为j,不放物品i时的最大价值。

递推公式为: dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i]] + value[j])

3. 初始条件
  • 当背包容量为0时,那么不管从哪几个物体中选,最大价值总为0.
  • 当i为0时,即只能选择放入物品0或不放入物品0,想得到最大价值,肯定选择物品0最好, 但如果物品0重量大于背包容量时就无法放入,最大价值为0。
4. 遍历顺序

dp[i][j]由[i][j]位置的上方或者左上方得到,可以先遍历物品,也可以先遍历容量,我选择前者。具体步骤如下:

首先从dp[1][1]开始计算,当前物品1的重量(3)超过了背包总容量(1),所以无论之前的物品(这里指物品0)有没有放入背包,物品1都不可能放进去,所以背包的最大价值和在当前容量下放入物品1前的最大价值相同,即dp[1][1] = dp[0][1] = 15。dp[1][2]同理。

当背包扩容到3(即j = 3)时,直观来看,我们可以选择放入物品1,如果放入,就不能同时放入物品0,那么价值为20,如果不放物品1,可能的最大价值为只放物品0的价值,即15,因为20>15, 所以dp[1][3] = 20。把上述想法抽象总结如下:

容量大于物品1的容量,说明可以放入物品1。如果放入物品1,那留给前面的物体(这里指物品0)的容量只有j-wright[j](这里为0),所以前面物体能创造的最大价值为dp[i-1][j-weight[j]], 加上物品j后的价值为dp[i - 1][j - weight[j]] + value[i], 如果不放入物品1,那就和之前的情况一样,即dp[i-1][j]。取这两种情况价值大的,即max(dp[i - 1][j - weight[j]] + value[i], dp[i-1][j])。

5. 举例推导dp数组

在纸上举例,能写出下面的数组。

代码实现

在ACM模式下,Python的输入模式基础语句为下:

# 读取一个整数
n = int(input()) 

# 一行里有n个整数, 表示数据
a = list(map(int, input(),split()))

# 一行里面有两个整数
n, m = map(int, input().split()) 

# 如果有多行数据,则按照每行的顺序依次执行上述对应指令

objNum, bagWeight = map(int, input().split())

weight = [int(i) for i in input().split()]
value = [int(i) for i in input().split()]

dp = [[0]*(bagWeight+1) for i in range(objNum)]
for j in range(bagWeight+1):
    if j >= weight[0]:
        dp[0][j] = value[0]

for i in range(1, objNum): # 遍历
    for j in range(1, bagWeight+1):
        if weight[i] > j:
            dp[i][j] = dp[i-1][j]
        else:
            dp[i][j] = max(dp[i-1][j], dp[i-1][j - weight[i]] + value[i])
            
print(dp[objNum - 1][bagWeight])

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1437469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

#免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程

Mac电脑苹果芯片读写NTFS硬盘bash脚本 (ntfs.sh脚本内容在本文最后面) ntfs.sh脚本可以将Mac系统(苹果M系芯片)上的NTFS硬盘改成可读写的挂载方式,从而可以直接往NTFS硬盘写入数据。此脚本免费,使用过程中无需下载任何收费软件。…

SpringBoo+Vue构建简洁日志文件查看系统

点击下载《SpringBooVue构建日志文件查看系统(源代码)》 1. 前言 想必经常做java开发的小伙伴,其大多数服务都是运行在linux系统上的,当遇到一些比较棘手的bug需要处理时,经常要上服务器去捞日志,然后通过…

网络空间内生安全数学基础(2)——编码信道数学模型

目录 (零)这篇博客在干什么(一)内生安全与香农信道编码定理(二)基本定义(三)编码信道存在定理(三.壹)编码信道存在第一定理(三.贰)编码…

Python程序员面试题精选(1)

本文精心挑选了10道Python程序员面试题,覆盖了Python的多个核心领域,包括装饰器、lambda函数、列表推导式、生成器、全局解释器锁(GIL)、单例模式以及上下文管理器等。每道题都附有简洁的代码示例,帮助读者更好地理解和应用相关知识点。 题目…

数据结构与算法之美学习笔记:50 | 索引:如何在海量数据中快速查找某个数据?

目录 前言为什么需要索引?索引的需求定义构建索引常用的数据结构有哪些?总结引申 前言 本节课程思维导图: 在第 48 节中,我们讲了 MySQL 数据库索引的实现原理。MySQL 底层依赖的是 B 树这种数据结构。留言里有同学问我&#xff…

《山雨欲来-知道创宇 2023 年度 APT 威胁分析总结报告》

下载链接: https://pan.baidu.com/s/1eaIOyTk12d9mcuqDGzMYYQ?pwdzdcy 提取码: zdcy

VSCode无法启动:Waiting for server log...

问题基本情况 [13:30:20.720] > code 1.86.0 (commit 05047486b6df5eb8d44b2ecd70ea3bdf775fd937) [13:30:20.724] > Running ssh connection command... /var/fpwork/reiss/vscdata/server/cplane/.vscode-server/code-05047486b6df5eb8d44b2ecd70ea3bdf775fd937 comman…

C++中的析构函数

一、析构函数概念 析构函数不是完成对象的销毁,对象的销毁是由编译器完成的。析构函数完成的是对象中资源的清理工作。通常是对对象中动态开辟的空间进行清理。 二、析构函数特性 1.析构函数的函数名是 ~类名 2.析构函数无参数无返回值 3.一个类中只能有一个析…

有趣的CSS - 旋转的太极图

目录 整体效果核心代码html 代码css 部分代码 完整代码如下html 页面css 样式页面渲染效果 整体效果 使用 :before 、:after 伪元素以及 animation 属性画一个顺时针旋转的太极图。 核心代码部分,简要说明了写法思路;完整代码在最后,可直接复…

python 函数式编程入门:Lambda 函数的魅力

python 函数式编程入门:Lambda 函数的魅力 介绍Lambda 函数的应用排序过滤映射map、filter、reduce数据转换和筛选 介绍 Lambda 函数是 Python 中一个强大的功能,它可以快速创建匿名函数。在函数式编程中,lambda 函数发挥着至关重要的作用。…

消息队列使用的四种场景介绍

一、简介 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。 实现高性能,高可用,可伸缩和最终一致性架构。 使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ…

java内部类概述及使用方法

前言: 打好基础,daydayup! 内部类 内部类概述: 内部类是类的五大成分之一(成员变量,方法,构造器,内部类,代码块),如果一个类定义在另一个类的内部&#xff…

『运维备忘录』之 Yum 命令详解

运维人员不仅要熟悉操作系统、服务器、网络等只是,甚至对于开发相关的也要有所了解。很多运维工作者可能一时半会记不住那么多命令、代码、方法、原理或者用法等等。这里我将结合自身工作,持续给大家更新运维工作所需要接触到的知识点,希望大…

什么是UI设计?

用户界面(UI)它是人与机器互动的载体,也是用户体验(UX)一个组成部分。用户界面由视觉设计 (即传达产品的外观和感觉) 和交互设计 (即元素的功能和逻辑组织) 两部分组成。用户界面设计的目标是创建一个用户界面&#xf…

新版本nginx安装提示需要openssl的问题

新版本的nginx安装的时候未发现openssl的路径,有两种方式解决 方式一: 找到本地nginx的解压目录中 ,例如我的放到root下面了。 进入 /root/nginx1.24.0/auto/lib/openssl/conf 目录下修改内容 ,这两行都需要修改,…

TCP 粘包/拆包

文章目录 概述粘包拆包发生场景解决TCP粘包和拆包问题的常见方法Netty对粘包和拆包问题的处理小结 概述 TCP的粘包和拆包问题往往出现在基于TCP协议的通讯中,比如RPC框架、Netty等 TCP 粘包/拆包 就是你基于 TCP 发送数据的时候,出现了多个字符串“粘”…

微信小程序(三十七)选项点击高亮效果

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.选择性渲染类 2.以数字为需渲染内容&#xff08;数量&#xff09; 源码&#xff1a; index.wxml <view class"Area"><!-- {{activeNumindex?Active:}}是选择性添加类名进行渲染 -->&l…

P1808 单词分类

P1808 单词分类 题目描述 Oliver 为了学好英语决定苦背单词&#xff0c;但很快他发现要直接记住杂乱无章的单词非常困难&#xff0c;他决定对单词进行分类。 两个单词可以分为一类当且仅当组成这两个单词的各个字母的数量均相等。 例如 AABAC&#xff0c;它和 CBAAA 就可以…

Linux(三)--文件系统

Linux命令简介 [rootlocalhost ~]# 表示 Linux 系统的命令提示符。 []&#xff1a;这是提示符的分隔符号&#xff0c;没有特殊含义。 root&#xff1a;显示的是当前的登录用户&#xff0c;笔者现在使用的是 root 用户登录。 &#xff1a;分隔符号&#xff0c;没有特殊含义。 l…

【数据分享】1929-2023年全球站点的逐月平均降水量(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;说到常用的降水数据&#xff0c;最详细的降水数据是具体到气象监测站点的降水数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全…