当前位置: 首页 > news >正文

动态规划 之 背包问题

文章目录

  • 0-1背包问题
    • 2915.和为目标值的最长子序列的长度
    • 494.目标和
  • 完全背包问题
    • 322.零钱兑换
    • 518.零钱兑换II
  • 多重背包
    • 2585.获得分数的方法数
  • 分组背包
    • 1155.掷骰子等于目标和的方法数

背包问题是动态规划一个很重要的一类题目,主要分为0-1背包问题以及完全背包问题

基础的知识请看另一个博客
动态规划之背包问题

  • 通俗来说,可以这么理解,0-1背包问题,用于求解选择问题,结果存在一个target的限制
    • 传统的0-1背包问题,<=target下的最大价值数
    • 非连续子数列的=target的最长长度
  • 两层循环,外层循环是我们的nums[i],也就是可选的商品,内层循环是target也就是对于空间的遍历
    属于的是组合问题,要区别于排列问题,要是排列问题,外层循环是空间,内层循环是nums商品

对于这个排列还是组合的问题,请看我的另一博客
动态规划 之 排列与组合问题

  • 0-1背包和完全背包的问题,总的来说递推公式十分相似,区别在于递推公式
    • 0-1背包问题是 d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − w [ i ] ] + v [ i ] ) dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]) dp[i][j]=max(dp[i1][j],dp[i1][jw[i]]+v[i])
    • 完全背包问题是 d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − w [ i ] ] + v [ i ] ) dp[i][j] = max(dp[i-1][j], dp[i][j-w[i]] + v[i]) dp[i][j]=max(dp[i1][j],dp[i][jw[i]]+v[i])
  • 如何理解?
  • 答:在0-1背包问题中,对于选与不选当前的元素nums[i],我们都只需考虑前i-1个物品的情况,所以是max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);但是对于完全背包问题的时候,不选当前的nums[i],我们就是只需考虑前i-1个物品,否则就是得考虑前i个物品的情况,所以是max(dp[i-1][j], dp[i][j-w[i]] + v[i])

0-1背包问题

2915.和为目标值的最长子序列的长度

2915.和为目标值的最长子序列的长度

在这里插入图片描述

思路分析:由于子序列是运行非连续的,并且又是求解的是值为target的最长长度,我们就可以思考,如何缩小化我们的问题?定义dp[i][j]表示前i种商品中,值为j的最长的长度,那么一个dp[i][j]就可以由前面的dp[i-1][j]和dp[i-1][j-nums[i]]+1的较大值转移而来

class Solution:def lengthOfLongestSubsequence(self, nums: List[int], target: int) -> int:# dp[i][j] 定义为 前i种物品中,价值为j的方案数# 0-1 背包问题 的递推公式 当 j >= nums[i] 的时候, m = len(nums)# 典型的一个0-1背包问题# 定义dp[i][j] 表示前i个物品中,和为j的最大长度# 赋值为负无穷表示无法找到,不能全部都赋值为0dp = [[-inf]*(target+1) for _ in range(m+1)]# 分为选与不选的问题,dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]] # 这个赋值很重要dp[0][0] = 0for i in range(m):for j in range(target+1):# 当无法更新的时候,dp的值就是前i-1的时候相同if j < nums[i]:dp[i+1][j] = dp[i][j]else:# 原本的递推公式 dp[i][j] = max(dp[i-1][j],dp[i-1][j-nums[i]]+1)dp[i+1][j] = max(dp[i][j], dp[i][j-nums[i]]+1)return dp[m][target] if dp[m][target] > 0 else -1

494.目标和

494.目标和

在这里插入图片描述

思路分析:这题明面上,要你选择要加的数和减去的数字,实际上你可以通过转化,为只用求解要加上的数字或者要减去的数字为对应转化之后的一个newtarget,然后照着2915.和为目标值的最长子序列的长度一样的思路去做,不过由于这题求解的是方案数,所以对应的递推公式以及初始值不一样

详细的分析参考灵神的分析

class Solution:def findTargetSumWays(self, nums: List[int], target: int) -> int:# 类似于0-1背包问题,求解的是运算结果等于target的表达式的数目# 我们可以照常选择正数zheng,那么对应的负数就是sum(nums) - zheng# dp[i][j] 定义为前i个数字中,值为j的数目# dp[i][j] = dp[i-1][j-nums[i]] + dp[i-1][j+nums[i]] ,计算nums[i]=0也没关系,+,-0算两个表达式# 那么dp数组怎么开这个target,原本的困惑,就是选了正数还要管这个target的范围# 由式子,选取正数的和为p,要减去的数字和为q,有p+q=s,p-q = target,就可以求解出p与q的值即可# 我们只要开的空间等于其中一个即可,也可以去一个绝对值都算上s = sum(nums) - abs(target)if s<0 or s%2 == 1:return 0m = s // 2n = len(nums)dp = [[0]*(m+1) for _ in range(n+1)]# 赋初值为1,不然后面算不了dp[0][0] = 1for i in range(n):for j in range(m+1):if j < nums[i]:dp[i+1][j] = dp[i][j]else:# dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]dp[i+1][j] = dp[i][j] + dp[i][j-nums[i]]return dp[n][m]

完全背包问题

322.零钱兑换

322.零钱兑换

在这里插入图片描述

思路分析:这是一个完全背包问题,老样子,由于求解的是最小数目,所以初始值我们设置为float('inf'),然后再初始化dp[0][0]=1

class Solution:def coinChange(self, coins: List[int], amount: int) -> int:# 最少的硬币数目,硬币可以重复选,所以是完全背包问题n = len(coins)dp = [[float('inf')]*(amount+1) for _ in range(n+1)]# 定义递推公式,dp[i][j]表示前i种硬币,组成面值为j的最少硬币数目# 当j>= nums[i] 的时候,dp[i][j] = min(dp[i-1][j],dp[i][j-nums[i]])dp[0][0] = 0for i in range(n):for j in range(amount+1):if j < coins[i]:# 原本dp[i][j] = dp[i-1][j]dp[i+1][j] = dp[i][j]else:# 原本dp[i][j] = min(dp[i-1][j],dp[i][j-nums[i]]+1)dp[i+1][j] = min(dp[i][j],dp[i+1][j-coins[i]]+1)return dp[n][amount] if dp[n][amount] != float('inf') else -1

518.零钱兑换II

518.零钱兑换II

在这里插入图片描述

思路分析:完全背包问题,与322.零钱兑换的区别是,后者求解是最少的硬币数,而本题求解的是 达到amount的方案数,两种问题带来的dp数组的初始值和dp[0][0]的值不一样

  • 当求解的是类似于322.零钱兑换达到amount的最少硬币数,初始值为float('inf'),dp[0][0]=0
  • 当求解的是类似于518.零钱兑换II达到amount的方案数,初始值为0,dp[0][0]=1
class Solution:def change(self, amount: int, coins: List[int]) -> int:# 区别与零钱兑换I,这个求解的是组合数n = len(coins)dp = [[0]*(amount+1) for _ in range(n+1)]dp[0][0] = 1for i in range(n):for j in range(amount+1):if j < coins[i]:# dp[i][j] = dp[i-1][j]dp[i+1][j] = dp[i][j]else:# dp[i][j] = dp[i-1][j] + dp[i][j-coins[i]]dp[i+1][j] = dp[i][j] + dp[i+1][j-coins[i]]return dp[n][amount]
  • 这个零钱兑换II是组合问题,当出现排序问题如何解决?参照下面的博客

动态规划 之 排列与组合问题

多重背包

多重背包问题:在完全背包的基础上,限制每一个物品的数量,需要判断我们的空间j到底可以容纳下几个第i个物品,就有递推公式dp[i][j] = dp[i][j]+dp[i-1][j-z*marks]

2585.获得分数的方法数

2585.获得分数的方法数

在这里插入图片描述

思路分析:完全背包问题和0-1背包问题的结合,但是又有新的元素的出现,递推公式有所不同

  • 0-1背包问题 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i − 1 ] [ j − n u m s [ i ] ] dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]] dp[i][j]=dp[i1][j]+dp[i1][jnums[i]]
  • 完全背包问题 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − n u m s [ i ] ] dp[i][j]=dp[i-1][j]+dp[i][j-nums[i]] dp[i][j]=dp[i1][j]+dp[i][jnums[i]]
  • 多重背包问题 d p [ i ] [ j ] = d p [ i ] [ j ] + d p [ i − 1 ] [ j − n u m s [ i ] ∗ z ] dp[i][j]=dp[i][j]+dp[i-1][j-nums[i]*z] dp[i][j]=dp[i][j]+dp[i1][jnums[i]z]
  • 完全背包问题的累加的情况体现在dp[i][j-nums[i]],这个多重背包问题的累加体现在dp[i][j]
class Solution:def waysToReachTarget(self, target: int, types: List[List[int]]) -> int:# 完全背包问题,不过可以参照这个零钱兑换的思路去做,不过每次的时候要限制mod = 10**9 + 7n = len(types)dp = [[0]*(target+1) for _ in range(n+1)]dp[0][0] = 1# for i,c in enumerate(types):count,marks = c[0],c[1]for j in range(target+1):# 当不够的时候,那么就有 dp[i][j] = dp[i-1][j]dp[i+1][j] = dp[i][j]for z in range(1,count+1):if j >= z*marks:# 多重背包问题,dp[i][j] = dp[i][j] + dp[i-1][j-nums[i]*z]# 这个dp[i+1][j]最初始的值是外部的dp[i][j],我们得考虑选择z个的情况,每次都要加上之前的情况# 如果只是单纯的使用dp[i+1][j] = (dp[i][j] + dp[i][j - z * types[i][1]]) % mod# 那就是并没有正确累加先前的情况dp[i+1][j] = (dp[i+1][j] + dp[i][j - z * marks]) % modreturn dp[n][target]

分组背包

分组背包:就是有n组物品,每个物品的值都不一样,你可以选择一个物品

1155.掷骰子等于目标和的方法数

1155.掷骰子等于目标和的方法数

在这里插入图片描述

思路分析:

# 先放一个递归的方法
class Solution:def numRollsToTarget(self, n: int, k: int, target: int) -> int:mod = 10**9 + 7# 这个的意思是什么?一共有k种物体,k种物体加起来一共n个# 可以从递归入手,定义dfs(i,j)表示使用i个骰子,丢出j的点数# 当然,这个dfs(i,j) 可以由 dfs(i-1,j-1) + dfs(i-1,j-2)···+dfs(i-1,j-k)一起加起来# 递归返回的时候使用的是 i <=0 , j< i@cachedef dfs(i,j):# 得到结果,及时返回1if i == 0 and j == 0:return 1# i 不能<=0 ,同时要组合的结果j不能小于i,因为剩余i个骰子,最少也得是i(全部为1)if i <= 0 or j<i:return 0ans = 0# 枚举for z in range(1,k+1):ans += dfs(i-1,j-z)return ans % modreturn dfs(n,target) 

动态规划
灵神分析

class Solution:def numRollsToTarget(self, n: int, k: int, target: int) -> int:mod = 10**9 + 7           # 1:1 翻译为 动态规划,dp[i][j] 表示投掷出i个骰子,组合为点数j的方案数if not (n <= target <= n * k):return 0  # 无法组成 targetdp = [[0]*(target+1) for _ in range(n+1)]dp[0][0] = 1for i in range(n):# 遍历可以找得到的空间for j in range(target+1):for z in range(1,min(k+1,j+1)):dp[i+1][j] = (dp[i+1][j] + dp[i][j-z])%modreturn dp[n][-1]

相关文章:

动态规划 之 背包问题

文章目录 0-1背包问题2915.和为目标值的最长子序列的长度494.目标和 完全背包问题322.零钱兑换518.零钱兑换II 多重背包2585.获得分数的方法数 分组背包1155.掷骰子等于目标和的方法数 背包问题是动态规划一个很重要的一类题目&#xff0c;主要分为0-1背包问题以及完全背包问题…...

【Azure 架构师学习笔记】- Azure Databricks (11) -- UC搭建

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (10) – UC 使用 前言 由于ADB 的更新速度很快&#xff0c;在几个月之后重新搭建ADB 时发现UC 已经更新了很多&#xff0c;为了后续做ADB 的功…...

RTMP(Real-Time Messaging Protocol)

RTMP&#xff08;Real-Time Messaging Protocol&#xff09;是一种用于实时音视频和数据传输的协议&#xff0c;常见于直播和流媒体应用。 一 RTSP 协商消息 一、消息类型&#xff08;Message Types&#xff09; RTMP消息分为多种类型&#xff0c;通过Message Type ID标识&a…...

docker容器部署jar应用导入文件时候报缺少字体错误解决

如题&#xff0c;在导入文件时候报错如下&#xff1a; Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager 经查是缺少对应字体&#xff0c;解决办法有两张&#xff1a; 第一种&#xff1a;…...

贪吃蛇解析

目录 文章结尾有代码可自取 Win32API 光标的隐藏 获取按键信息 控制光标位置 游戏开始前的准备 游戏准备及介绍 加载和欢迎界面 打印游戏指南 运行游戏 打印墙体和说明 设置蛇的各个信息 初始化及打印蛇 创造食物 运行游戏 1&#xff09;打印得分情况 2&#…...

vue非组件的初学笔记

1.创建Vue实例&#xff0c;初始化渲染的核心 准备容器引包创建Vue实例new Vue() el用来指定控制的盒子data提供数据 2.插值表达式 作用利用表达式插值&#xff0c;将数据渲染到页面中 格式{{表达式}} 注意点 表达式的数据要在data中存在表达式是可计算结果的语句插值表达式…...

LeetCode 热题 100_单词搜索(60_79_中等_C++)(深度优先搜索(回溯))(初始化二维vector的大小)

LeetCode 热题 100_单词搜索&#xff08;60_79&#xff09; 题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;深度优先搜索&#xff08;回溯&#xff09;&#xff09;&#xff1a; 代码实现代码实现&#xff08;思路一&am…...

js闭包,跨域

js闭包&#xff0c;跨域 闭包 想象一下&#xff0c;你家有个大仓库&#xff08;函数&#xff09;&#xff0c;仓库里放着各种东西&#xff08;变量&#xff09;。一般情况下&#xff0c;你从仓库外面是看不到也拿不到仓库里的东西的。但是&#xff0c;闭包就像是你在仓库里留…...

算法练习(力扣-BFS)——102. 二叉树的层序遍历

题目描述&#xff08;简要概括&#xff09; 题目链接&#xff1a;102. 二叉树的层序遍历 - 力扣&#xff08;LeetCode&#xff09; 题目要求对给定的二叉树进行层序遍历&#xff08;从上到下&#xff0c;从左到右&#xff09;&#xff0c;并返回遍历的结果。层序遍历是一种基…...

Jetson Agx Orin平台preferred_stride调试记录--1924x720图像异常

1.问题描述 硬件: AGX Orin 在Jetpack 5.0.1和Jetpack 5.0.2上测试验证 图像分辨率在1920x720和1024x1920下图像采集正常 但是当采集图像分辨率为1924x720视频时,图像输出异常 像素格式:yuv_uyvy16 gstreamer命令如下 gst-launch-1.0 v4l2src device=/dev/video0 ! …...

nlp|微调大语言模型初探索(2),训练自己的聊天机器人

前言 上篇文章记录了具体的微调语言大模型步骤&#xff0c;以及在微调过程中可能遇见的各种报错&#xff0c;美中不足的是只是基于开源数据集的微调&#xff0c;今天来记录一下怎么基于自己的数据集去微调大语言模型&#xff0c;训练自己的智能机器人&#xff01;&#xff01;&…...

win11安装wsl报错:无法解析服务器的名称或地址(启用wsl2)

1. 启用wsl报错如下 # 查看可安装的 wsl --install wsl --list --online此原因是因为没有开启DNS的原因&#xff0c;所以需要我们手动开启DNS。 2. 按照如下配置即可 Google的DNS&#xff08;8.8.8.8和8.8.4.4) 全国通用DNS地址 (114.114.114.114) 3. 运行以下命令来重启 WSL…...

Gentleman:优雅的Go语言HTTP客户端工具包

gentlemen介绍&#xff0c;特点等 插件驱动架构&#xff1a;Gentleman的核心特点是其插件系统&#xff0c;允许用户注册和重用各种自定义插件&#xff0c;如重试策略或动态服务器发现&#xff0c;以增强HTTP客户端的功能。 中间件层&#xff1a;项目内置了一个上下文感知的层次…...

解锁豆瓣高清海报(三)从深度爬虫到URL构造,实现极速下载

脚本地址: 项目地址: Gazer PosterBandit_v2.py 前瞻 之前的 PosterBandit.py 是按照深度爬虫的思路一步步进入海报界面来爬取, 是个值得学习的思路, 但缺点是它爬取慢, 仍然容易碰到豆瓣的 418 错误, 本文也会指出彻底解决旧版 418 错误的方法并提高爬取速度. 现在我将介绍…...

IDEA单元测试插件 SquareTest 延长试用期权限

SquareTest是一款强大的IDEA单元测试生成插件工具&#xff0c;具体使用方法就不过多介绍了&#xff0c;这里主要介绍变更试用期&#xff0c;方便大家使用 配置信息 我的电脑安装前提配置条件 IntelliJ IDEA 2023.2windows 系统 软件安装 IntelliJ IDEA 直接安装插件Squar…...

PLC的五个学习步骤

五个学习步骤详解&#xff1a; 1. 夯实电气基础 (第一步) 核心思想: PLC控制技术是建立在传统电气控制技术之上的&#xff0c;因此扎实的电气基础至关重要。学习内容: 电气元件原理: 深入理解继电器、接触器、按钮、三相异步电机等常用电气元件的工作原理。这是理解电气控制回…...

深度学习05 ResNet残差网络

目录 传统卷积神经网络存在的问题 如何解决 批量归一化BatchNormalization, BN 残差连接方式 ​残差结构 ResNet网络 ResNet 网络是在 2015年 由微软实验室中的何凯明等几位大神提出&#xff0c;斩获当年ImageNet竞赛中分类任务第一名&#xff0c;目标检测第一名。获得CO…...

卷积神经网络CNN

目录 一、CNN概述 二、图像基础知识 三、卷积层 3.1 卷积的计算 3.2 Padding 3.3 Stride 3.4 多通道卷积计算 3.5 多卷积核卷积计算 3.6 特征图大小计算 3.7 Pytorch 卷积层API 四、池化层 4.1 池化计算 4.2 Stride 4.3 Padding 4.4 多通道池化计算 4.5 Pytorc…...

Android:播放Rtsp视频流的两种方式

一.SurfaceView Mediaplayer XML中添加SurfaceView: <SurfaceViewandroid:id"id/surface_view"android:layout_width"match_parent"android:layout_height"match_parent"/> Activity代码&#xff1a; package com.android.rtsp;impor…...

web信息泄露 ctfshow-web入门web1-web10

01做题思路 判断做题的思路是读取&#xff0c;写入&#xff0c;还是执行判断大概的类型&#xff0c;有登录逻辑就尝试sql注入&#xff0c;有下载逻辑就尝试文件读取&#xff0c;有源码就做源码审计 02信息泄露及利用 robots.txt 以ctfshow的web1为例&#xff0c;访问robots…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...