代码随想录算法训练营第三十七天 | 完全背包 518.零钱兑换 Ⅱ 377.组合总和Ⅳ 70.爬楼梯(进阶版)

完全背包:

文章链接
题目链接:卡码网 52.携带研究材料
与01背包的区别在于物品数量无限,因此同一种物品可以取多次。
递推式如下:

  • 二维:dp[i][j] = max(dp[i - 1][j], dp[i][j - weights[i]] + value[i]),因为同样物品数量无限,因此选了该物品后剩下背包容量的最大价值应当为dp[i][j - weight[i]] + value[i],即当前行的,因为第 i 个物品还可以继续选
  • 一维:dp[j] = max(dp[j], dp[j - weights[i]] + value[i])
    遍历顺序:
    无论是一维数组还是二维数组,遍历背包和物品的先后顺序无所谓,但是遍历背包要顺序遍历,因为已经选了的物品后面还可以继续选。
class Solution():
	# 一维数组
    def bagWeightOne(self):
        N, bagweight = [int(x) for x in input().split()]
        weights, value = [], []
        for _ in range(N):
            w, v = [int(x) for x in input().split()]
            weights.append(w)
            value.append(v)
        
        dp = [0] * (bagweight + 1)
        
        for i in range(N):
            for j in range(weights[i], bagweight + 1):
                dp[j] = max(dp[j], dp[j - weights[i]] + value[i])
        return dp[bagweight]
    
	# 二维数组
    def bagWeightTwo(self):
        N, bagweight = [int(x) for x in input().split()]
        weights, value = [], []
        for _ in range(N):
            w, v = [int(x) for x in input().split()]
            weights.append(w)
            value.append(v)
        
        dp = [[0] * (bagweight + 1) for _ in range(N)]
        # 初始化
        for j in range(weights[0], bagweight + 1):
            dp[0][j] = dp[0][j - weights[0]] + value[0]
        # 递推
        for i in range(1, N):
            for j in range(0, bagweight + 1):
                if j >= weights[i]:
                	# 注意max的第二个参数
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - weights[i]] + value[i])
                else:
                    dp[i][j] = dp[i - 1][j]
        return dp[-1][-1]
        

solution = Solution()
print(solution.bagWeightTwo())

感悟:

因为完全背包同一物品可以选多次,联系到01背包一维数组时背包容量逆序为了让物品只选一次,因此完全背包一维数组背包容量为顺序,再联系到递推式,因此先背包容量后物品还是先物品后背包容量都可以,但是需要顺序遍历背包容量


518.零钱兑换 Ⅱ:

文章链接
题目链接:518.零钱兑换 Ⅱ

思路:

本题是要求组合数,因此dp数组保存的也应当为组合数
动规五部曲

  • ① dp数组及下标的含义
    dp[j] : 可以凑成背包容量(总金额)为 j 的硬币组合数为dp[j]
  • ② 递推式
    dp[j] += dp[j - coins[i]]
  • ③ 初始化
    dp[0]初始化为1,可以认为总金额为0时可以凑成总金额的组合数为1,其余非0下标初始化为0
  • ④ 遍历顺序
    本题要求的是组合数,如果先遍历背包容量后遍历物品的话,以[1, 5]为例,背包容量的每个值,都经过了1和5的计算,得到了{1, 5}和{5, 1}两种情况,计算的是排列数;如果先遍历物品后遍历背包的话,还是以[1, 5]为例,那么得到的方法数量只有{1, 5}一种情况,此时计算的是组合数
    因此要采用先物品后背包容量的遍历顺序
  • ⑤ 举例
    以[1, 2, 5],amount = 5举例
    在这里插入图片描述
class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        dp = [0] * (amount + 1)
        dp[0] = 1
        for coin in coins:
            for j in range(coin, amount + 1):
                dp[j] += dp[j - coin]
        return dp[amount]
        

感悟:

完全背包应用的先后遍历顺序


LeetCode 377.组合总和Ⅳ:

文章链接
题目链接:377.组合总和Ⅳ

思路

分析本题可知,nums数组中的数可以多次选择,因此是完全背包,且顺序不同的序列被视为不同的组合,因此还是排列问题。
整体思路与上题相似,不同之处在于本题要求排列数,因此是先遍历背包容量后遍历物品
初始化部分因为nums为正数,所以dp[0]无意义,为例便于递推初始化为1,其余非0初始化为0,避免初始化数对递推结果产生影响
举例
在这里插入图片描述

class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        dp = [0] * (target + 1)
        dp[0] = 1
        # 求排列数,先背包容量后物品
        for j in range(1, target + 1):
            for num in nums:
                if num <= j:
                    dp[j] += dp[j - num]
        return dp[target]

感悟:

先仔细分析题目再敲代码


70.爬楼梯(进阶版):

文章链接
题目链接:卡码网 57.爬楼梯

思路:

首先分析题目,物品(每次可以爬的台阶数)为1-m,对应的重量和价值也为1~m,背包容量为n,且物品可以重复使用,因此是完全背包问题。
且先爬2阶再爬1阶和先爬1阶再爬2阶不同,因此为排列数,先遍历背包容量再遍历物品。
动态规划五部曲

  • ① dp数组及下标的含义
    dp[j] : 爬 j 阶台阶的的方法数为dp[j]
  • ② 递推式
    如果最后爬 i 阶台阶到了 j 阶台阶,方法数为dp[j - i](条件 j >= i)
    如果最后爬 < i 阶台阶到了 j 阶台阶,方法数为dp[j]
    因为题目需要的是多少不同的方法数,即排列总数
    dp[j] += dp[j - i]
  • ③ 初始化
    因为每次爬的台阶数都为正数,因此dp[0]无意义,为了便于递推,因此dp[0]初始化为1,其余下标非0初始化为0,避免初始值对递推结果造成影响
  • ④ 遍历顺序
    先遍历背包容量(需要的台阶数)再遍历物品(每次爬的台阶数)。
  • ⑤ 举例
    以m = 2, n = 3举例
    在这里插入图片描述
class Solution():
    def climbStair(self, m, n):
        if m >= n:
            return 1
        dp = [0] * (n + 1)
        dp[0] = 1
        # 求排列数,先遍历背包容量后遍历物品
        # 也可以这么理解,爬 i 阶台阶后到达 j 阶台阶的方法为dp[j - i] 
        for j in range(1, n + 1):
            # 递推公式需要i <= j,且i <= m
            for i in range(1, min(j + 1, m + 1)):
                dp[j] += dp[j - i]
        return dp[n]



n, m = [int(x) for x in input().split()]
solution = Solution()
print(solution.climbStair(m, n))

感悟:

先分析题目(01背包、完全背包、组合、排列、求最大值?)后确定动规五部曲。


学习收获:

  1. 完全背包问题及完全背包问题在组合、排列数上的应用。
  2. 完全背包问题是单个物品可以取多次,因此遍历顺序中遍历背包容量时为顺序遍历(一维数组)。
  3. 同时需要分析完全背包应用问题是求最大值还是求组合数、排列数。如果是求组合数,那么应当先遍历物品再遍历背包容量;如果求排列数,应当先遍历背包容量再遍历物品。
    以[1, 5]举例,先物品后背包的话,只会出现{1, 5}一种情况
    先背包后物品的话,会出现{1, 5}和{5, 1}两种情况
  4. 同时所给物品的weight和value的范围来确定如何初始化

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言心型代码解析

方法一 心型极坐标方程 爱心代码你真的理解吗 笛卡尔的心型公式&#xff1a; for (y 1.5; y > -1.5; y - 0.1) for (x -1.5; x < 1.5; x 0.05) 代码里面用了二个for循环&#xff0c;第一个代表y轴&#xff0c;第二个代表x轴 二个增加的单位不同&#xff0c;能使得…

C语言网络编程 -- TCP/iP协议

一、Socket简介 1.1 什么是socket socket通常也称作"套接字"&#xff0c;⽤于描述IP地址和端⼝&#xff0c;是⼀个通信链的句柄&#xff0c;应⽤ 程序通常通过"套接字"向⽹络发出请求或者应答⽹络请求。⽹络通信就是两个进程 间的通信&#xff0c;这两个进…

字符串接龙 /单词接龙 (BFs C#

卡码网 110和 力扣127 和LCq 108题都是一个解法 这两道题乍一看在结果处可能不一样 力扣要求 字符串里边必须包含对应的最后一个字符 而110不需要最后一个字符 但是在实验逻辑上是一致的 只是110需要把如果在set中找不到最后一个字符就直接返回0的逻辑删去 就可以了 这就是…

Transformer和BERT的区别

Transformer和BERT的区别比较表&#xff1a; 两者的位置编码&#xff1a; 为什么要对位置进行编码&#xff1f; Attention提取特征的时候&#xff0c;可以获取全局每个词对之间的关系&#xff0c;但是并没有显式保留时序信息&#xff0c;或者说位置信息。就算打乱序列中token…

python操作MySQL以及SQL综合案例

1.基础使用 学习目标&#xff1a;掌握python执行SQL语句操作MySQL数据库软件 打开cmd下载安装 安装成功 connection就是一个类&#xff0c;conn类对象。 因为位置不知道&#xff0c;所以使用关键字传参。 表明我们可以正常连接到MySQL 演示、执行非查询性质的SQL语句 pytho…

【报告PDF附下载】2024人工智能大模型技术财务应用蓝皮书

《人工智能大模型技术财务应用蓝皮书》 是一本探讨AI大模型技术在财务管理领域应用的权威指南。书中不仅概述了人工智能大模型技术的发展历程、典型特征和未来趋势&#xff0c;还详细介绍了它的体系架构和在财务领域的应用情况。 书中通过家用电器制造、银行、汽车企业、基础设…

快速上手vue3+js+Node.js

安装Navicat Premium Navicat Premium 创建一个空的文件夹&#xff08;用于配置node&#xff09; 生成pakeage.json文件 npm init -y 操作mysql npm i mysql2.18.1 安装express搭建web服务器 npm i express4.17.1安装cors解决跨域问题 npm i cors2.8.5创建app.js con…

【Python爬虫实战】DrissionPage 与 ChromiumPage:高效网页自动化与数据抓取的双利器

&#x1f308;个人主页&#xff1a;易辰君-CSDN博客 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、DrissionPage简介 &#xff08;一&#xff09;特点 &#xff08;二&#xff09;安装 &#xff08;三…

【JAVA】java 企业微信信息推送

前言 JAVA中 将信息 推送到企业微信 // 企微消息推送messageprivate String getMessage(String name, String problemType, String pushResults, Long orderId,java.util.Date submitTime, java.util.Date payTime) {String message "对接方&#xff1a;<font color\…

前端md5加密

npm下载 npm install --save ts-md5页面引入 import { Md5 } from ts-md5使用 const md5PwdMd5.hashStr("123456")md5Pwd&#xff08;加密后的数据&#xff09; .toUpperCase()方法转大写

DDRSYS,不同频点的时序参数配置说明,DBI/DM功能说明

文章目录 不同频点的时序参数配置说明LPDDR4 时序参数DFI 参数对应配置DDR3/4DBI功能说明&#xff0c;MC控制DBI情况 不同频点的时序参数配置说明 LPDDR4 时序参数 LP4的时序参数从JEDEC颗粒文档可以检索到读写的时序参数如下&#xff1a; 此图主要关注不同频点对应的RL和WL…

如何自学机器学习?

自学机器学习可以按照以下步骤进行&#xff1a; 一、基础知识准备 数学基础&#xff1a; 高等数学&#xff1a;学习微积分&#xff08;包括导数、微分、积分等&#xff09;、极限、级数等基本概念。这些知识是后续学习算法和优化方法的基础。 线性代数&#xff1a;掌握矩阵…

工程巡查应该怎么做?如何利用巡查管理软件?

工程行业&#xff0c;无论是建设单位&#xff0c;监理单位&#xff0c;还是施工单位&#xff0c;工程巡查几乎是每日必做的工作。然而&#xff0c;巡查过程中&#xff0c;传统的做法通常依赖手动记录、拍照上传、在微信群中进行汇报。这种方式需要建大量的微信群&#xff0c;不…

Scala入门基础(16)scala的包

Scala的包定义包定义包对象Scala的包的导入导入重命名 一.Scala的包 package&#xff08;包&#xff1a;一个容器。可以把类&#xff0c;对象&#xff0c;包&#xff0c;装入。 好处&#xff1a; 区分同名的类&#xff1b;类很多时&#xff0c;更好地管理类&#xff1b;控制…

协程6 --- HOOK

文章目录 HOOK 概述链接运行时动态链接 linux上的常见HOOK方式修改函数指针用户态动态库拦截getpidmalloc 第一版malloc 第二版malloc/free通过指针获取到空间大小malloc 第三版strncmp 内核态系统调用拦截堆栈式文件系统 协程的HOOK HOOK 概述 原理&#xff1a;修改符号指向 …

MySQL中,GROUP BY 分组函数

文章目录 示例查询&#xff1a;按性别分组统计每组信息示例查询&#xff1a;按性别分组显示详细信息示例查询&#xff1a;按性别分组并计算平均年龄,如果你还想统计每个性别的平均年龄&#xff0c;可以结合AVG()函数&#xff1a;说明 示例查询&#xff1a;按性别分组统计每组信…

免费数据集网站

1、DataSearch https://datasetsearch.research.google.comhttp://DataSearch 2、FindData findata-科学数据搜索引擎https://www.findata.cn/ 3、Kaggle Kaggle: Your Machine Learning and Data Science CommunityKaggle is the world’s largest data science community …

十二:java web(4)-- Spring核心基础

目录 创建项目 Spring 核心基础 Spring 容器 Spring 容器的作用 Spring 容器的工作流程 Bean Bean 的生命周期 IOC&#xff08;控制反转&#xff09;与依赖注入&#xff08;DI&#xff09; 控制反转的概念 依赖注入的几种方式&#xff08;构造器注入、Setter 注入、接…

MybatisPlus入门(八)MybatisPlus-DQL编程控制

一、字段映射与表名映射 数据库表和实体类名称一样自动关联&#xff0c;数据库表和实体类有部分情况不一样。 问题一&#xff1a;表名与编码开发设计不同步&#xff0c;表名和实体类名称不一致。 解决办法&#xff1a; 在模型类上方&#xff0c;使用TableName注解&#xf…

亚信安全新一代WAF:抵御勒索攻击的坚固防线

近年来&#xff0c;勒索攻击已成为黑客的主要攻击手段。新型勒索攻击事件层出不穷&#xff0c;勒索攻击形势愈发严峻&#xff0c;已经对全球制造、金融、能源、医疗、政府组织等关键领域造成严重危害。如今&#xff0c;勒索攻击手段日趋成熟、攻击目标愈发明确&#xff0c;模式…