day44代码训练|动态规划part06

完全背包和01背包问题唯一不同的地方就是,每种物品有无限件

1. dp数组的含义

dp[i][j] 0-i物品,重量为j的容量时,最大的价值

2. 递推公式

dp[i][j] = max(dp[i-1][j],dp[i][j-weight[i]]+value[i]);

两种状态,不用物品i的话,直接是用dp[i-1][j]

选用物品的话,为了重复使用物品i,其实是dp[i][j-weight[i]]+value[i],因为对dp[i][...]都是仍有机会再次使用物品i得

3.初始化dp[...][0]=0 由于重量为0,不可能有价值

dp[0][...] dp[0][j] = dp[0][j-wi]+vi;

4. 遍历顺序

物品和背包在外循环都可以(因为是二维),对背包空间需要是正向遍历,因为需要同行的前面的数据

压缩为1维dp:

把二维dp压缩为一行滚动更新//把dp[i-1]拷贝到dp[i]上

1. dp数组的含义

dp[j]重量为j的容量时,最大的价值

2. 递推公式

dp[j] = max([j],dp[j-weight[i]]+value[i]);

两种状态,不用物品i的话,直接是用dp[i-1][j]

3.初始化

dp[0]=0;(背包没有任何空间)

其他也初始化为0(非负的最小值),不会影响循环中的更新(需要用max,如果初始值太大,会影响递推公式)

4. 遍历顺序

根据递推公式:必须要正向遍历背包,因为在二维的角度看,会用到同一行,之前的数据

压缩来看:当前的数据更新 只需要dp[j-wi]+vi <--> dp[i][j-wi]+vi(由于正向遍历,在遍历到当前位置的时候,已经在一维dp数组中在当前位置的前方《0,j-1》全部更新了dp[i]层的数据,而当前j位置及以后仍然是dp[i-1]层数据),和dp[j] <->dp[i-1][j](其实就是上一层遍历储存在dp[i-1]层的数据)

而背包与物品的循环内外层关系并不重要了

对于01背包问题

如果倒序遍历背包,然后背包循环还在外面的话,dp[j-w]还在初始化状态时,就把dp[j]从0层到i层更新完了,(最终只会装入一个物品,当前容量下能装下的某一个物品且其价值最大)

所以必须先遍历物品,再对每个物品进行背包空间上的倒序遍历,这样在对第i层的dp[j]进行递推的时候,dp[j-wi]并不是初始化的值,而是已经计算过第i-1层的值了

对于完全背包问题

如果是正序的话,不论先遍历背包还是先遍历物品

在递推更新dp[j] 的时候需要的

dp[i] = max(dp[j],dp[j-weight[i]]+value[i]); dp[j]对应第i-1层 dp[j-wi]对应第N层(N 为物品个数),是提前算好的数据,但是由于是取最值,所以第N层的dp[j-wi]也是可以的,只要最后是整体的最大值就行了。与顺序无关。所以及时使用之后的数据也不影响最后的结果

举例:

重量        价值
物品0115
物品1360
物品2430

先物品再背包

背包体积01234
物品0015304560
物品1015306075
物品2015306075

先背包再物品

背包体积01234
物品0015304575
物品10153060
物品20153060

其实遍历下来跟二维dp还是有所不同因为在更新dp[j=4] (dp[i=0][j=4])的时候本来应该应用dp[i=0][j=3]+v1来跟0比较大小,但是先背包再物品的遍历顺序让当时的dp[j=3]其实是dp[i=2][j=3],所以dp[j=4]在i=0的时候已经是75了,但是并不影响,因为我们要取的是最大值,什么顺序,什么时候最大,并不影响最后结果,所以可以改变循环顺序

但是后面一题跟顺序有关,就不能随意改变循环顺序了

518.零钱兑换II

给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。

由于是求组合数,所以跟顺序没有关系

例如示例:

5 = 2 + 2 + 1

5 = 2 + 1 + 2

这是一种组合,都是 2 2 1。

1. dp 数组及含义

2维:dp[i][j] 的定义如下:

若只使用前 i 个物品(可以重复使用),当背包容量为 j 时,有 dp[i][j] 种组合方法可以装满背包

1维:dp[j]:凑成总金额j的货币组合数为dp[j]

2. 递推公式

2维

如果你不把这第 i 个物品装入背包,也就是说你不使用 coins[i-1] 这个面值的硬币,那么凑出面额 j 的方法数 dp[i][j] 应该等于 dp[i-1][j],继承之前的结果。

如果你把这第 i 个物品装入了背包,也就是说你使用 coins[i-1] 这个面值的硬币,那么 dp[i][j] 应该等于 dp[i][j-coins[i-1]]

dp[i][j] = dp[i - 1][j]  + dp[i][j-coins[i-1]];

1维:

dp[j] += dp[j - nums[i]];

3. 初始化

2维:base case 为 dp[0][..] = 0, dp[..][0] = 1。i = 0 代表不使用任何硬币面值,这种情况下显然无法凑出任何金额;j = 0 代表需要凑出的目标金额为 0,那么什么都不做就是唯一的一种凑法。

1维:dp[..][0] = 1由此可得之:

dp[j=0]=1; (目标为0的时候什么都不放就是一种方法)

由2维的 dp[0][..] = 0也可以看出,其他dp[j]初始化为0 对1维递推公式来说也是,初始化为0才不会影响累加公式的结果

4. 遍历顺序:

2维:背包正序遍历即可

两个循环内外部影响

1维:

先物品再背包,公式计算时是:dp[j]<-> dp[i][j]=dp[j]<->dp[i-1][j]+ dp[j - nums[i]]<->dp[i][j-nums[i]]

可以跟2维公式对应上

如果先循环背包再循环物品,从某点开始,dp[j-nums[i]]本应该对应2维的dp[i][j-nums[i]]却对应的是dp[N][j-nums[i]],因为递推公式是累加,之后的结果都会相应跟二维dp数组发生越来越大的结果

dp[j]<-> dp[i][j]=dp[j]<->无法对应+ dp[j - nums[i]]<->无法对应

不同遍历方式一维dp数组打印:

例子:

  • 输入: amount = 5, coins = [1, 2, 5]

先物品再背包

012345
c1111111
c2112233
c5112234

先背包再物品

012345
c1111235
c2112358
c5112359

另一种理解方式:来源代码随想录

377. 组合总和 Ⅳ

其实本体本质不是一个完全背包问题,可以直接立即为:

每次能走1-n步的爬楼梯有多少种方法的问题

理解维爬楼梯问题后,可以简单直观的看出,我们必须先遍历到了第几层楼梯

再循环遍历这次爬几阶楼梯,这样每次dp[j]都讨论了会选择之前不同爬楼梯阶数的可能性dp[j]+=dp[j-nums[i]],所以其实把排列/顺序已经考虑在了其中

class Solution {
    public int combinationSum4(int[] nums, int target) {
        int[] dp = new int[target+1];
        dp[0]=1;
        for(int j=0;j<=target;j++){
            for(int i=0;i<nums.length;i++){
                if(j>=nums[i])dp[j]+=dp[j-nums[i]];
            }
        }
        return dp[target];
    }
}

如果要用二维来理解:如下:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

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

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

相关文章

【数论】质数

试除法判断质数 分解质因数 一个数可以被分解为质因数乘积 n &#xff0c;其中的pi都是质因数 那么怎么求pi及其指数呢&#xff1f; 我们将i一直从2~n/i循环&#xff0c;如果 n%i0&#xff0c;那么i一定是质因数&#xff0c;并且用一个while循环将n除以i&#xff0c;一直到…

蛇梯棋[中等]

一、题目 给你一个大小为n x n的整数矩阵board&#xff0c;方格按从1到n2编号&#xff0c;编号遵循 转行交替方式 &#xff0c;从左下角开始 &#xff08;即&#xff0c;从board[n - 1][0]开始&#xff09;每一行交替方向。玩家从棋盘上的方格1&#xff08;总是在最后一行、第…

礼品企业网站搭建的作用是什么

礼品一般分为企业定制礼品和零售现成礼品&#xff0c;二者都有很强的市场需求度。同时对礼品企业而言&#xff0c;一般主要以批发为主&#xff0c;客户也主要是零售商或企业。 1、拓客难 不同于零售&#xff0c;即使没有引流&#xff0c;入驻商场或街边小摊也总会有自然客户。…

【C++篇】Vector容器 Vector嵌套容器

文章目录 &#x1f354;简述vector&#x1f384;vector存放内置数据类型⭐创建一个vector容器⭐向容器里面插入数据⭐通过迭代器访问容器里面的数据⭐遍历&#x1f388;第一种遍历方式&#x1f388;第二种遍历方式&#x1f388;第三种遍历方式 &#x1f384;vector存放自定义数…

揭秘 Go 中 Goroutines 轻量级并发

理解 Goroutines、它们的效率以及同步挑战 并发是现代软件开发的一个基本概念&#xff0c;使程序能够同时执行多个任务。在 Go 编程领域&#xff0c;理解 Goroutines 是至关重要的。本文将全面概述 Goroutines&#xff0c;它们的轻量级特性&#xff0c;如何使用 go 关键字创建…

FPGA模块——以太网(1)MDIO读写

FPGA模块——以太网MDIO读写 MDIO接口介绍MDIO接口代码&#xff08;1&#xff09;MDIO接口驱动代码&#xff08;2&#xff09;使用MDIO驱动的代码 MDIO接口介绍 MDIO是串行管理接口。MAC 和 PHY 芯片有一个配置接口&#xff0c;即 MDIO 接口&#xff0c;可以配置 PHY 芯片的工…

Ubuntu 常用命令之 ifconfig 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 ifconfig 是一个用于配置和显示 Linux 内核中网络接口的系统管理命令。它用于配置&#xff0c;管理和查询 TCP/IP 网络接口参数。 ifconfig 命令的参数有很多&#xff0c;以下是一些常见的参数 up&#xff1a;激活指定的网络接口…

Java学习系列(五)

1.继承 继承是java面向对象编程技术的一块基石&#xff0c;因为它允许创建分等级层次的类。 继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类从父类继承方法&#xff0c;使得子类具有父类相…

实现单链表的基本操作(力扣、牛客刷题的基础笔试题常客)

本节来学习单链表的实现。在链表的刷题中&#xff0c;单链表占主导地位&#xff0c;很多oj题都在在单链表的背景下进行&#xff1b;而且很多链表的面试题都是以单链表为背景命题。所以&#xff0c;学好单链表的基本操作很重要 目录 一.介绍单链表 1.链表及单链表 2.定义一个…

生活中的物理2——人类迷惑行为(用笔扎手)

1实验 材料 笔、手 实验 1、先用手轻轻碰一下笔尖&#xff08;未成年人须家长监护&#xff09; 2、再用另一只手碰碰笔尾 你发现了什么&#xff1f;&#xff1f; 2发现 你会发现碰笔尖的手明显比碰笔尾的手更痛 你想想为什么 3原理 压强f/s 笔尖的面积明显比笔尾的小 …

C#文件操作(二)

一、前言 文章的续作前文是&#xff1a; C#文件操作&#xff08;一&#xff09;-CSDN博客https://blog.csdn.net/qq_71897293/article/details/135117922?spm1001.2014.3001.5501 二、流 流是序列化设备的抽象表示序列化设备可以线性方式储存数据并可按照同样的方式访问一次…

【QT】QGraphicsView和QGraphicsItem坐标转换

坐标转换 QGraphicsItem和QGraphicsView之间的坐标转换需要通过QGraphicsScene进行转换 QGraphicsView::mapToScene() - 视图 -> 场景QGraphicsView::mapFromScene() - 场景 -> 视图QGraphicsItem::mapToScene() - 图元 -> 场景QGraphicsItem::mapFromScene() - 场景 …

Java异常类分类,所有子类的父类是什么

1.异常的层次机构&#xff1a; 所有异常的父类是Throwable&#xff0c;它有两个子类&#xff0c;分别是Error和Exception。 2.Error&#xff1a; 表示系统错误&#xff0c;通常不能处理和恢复。比如StackOverFlowError或者OutOfMemoryError&#xff0c;出了问题只能结束程序…

【项目问题解决】% sql注入问题

目录 【项目问题解决】% sql注入问题 1.问题描述2.问题原因3.解决思路4.解决方案1.前端限制传入特殊字符2.后端拦截特殊字符-正则表达式3.后端拦截特殊字符-拦截器 5.总结6.参考 文章所属专区 项目问题解决 1.问题描述 在处理接口入参的一些sql注入问题&#xff0c;虽然通过M…

【matlab】绘制竖状双组渐变柱状图

【matlab】绘制竖状双组渐变柱状图

【krita】实时绘画 入门到精通 海报+电商+装修+人物

安装插件 首先打开comfyUI&#xff0c;再打开krita&#xff0c;出现问题提示&#xff0c; 打开 cd custom_nodes 输入命令 安装控件 git clone https://github.com/Acly/comfyui-tooling-nodes.git krita基础设置 设置模型 设置lora &#xff08;可设置lora强度 增加更多…

使用yarn安装electron时手动选择版本

访问1Password或者其他可以提供随机字符的网站&#xff0c;获取随机密码运行安装命令 操作要点&#xff0c;必须触发Couldnt find any versions for "electron" that matches "*"才算成功 将复制的随机密码粘贴到后面 例如&#xff1a;yarn add --dev elec…

智能优化算法应用:基于堆优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于堆优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于堆优化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.堆优化算法4.实验参数设定5.算法结果6.参考文…

Python自动化测试系列[v1.0.0][常见页面操作处理]

[智能等待] # 用于实现智能等待页面元素的出现 # encoding utf-8 """ __title__ __author__ davieyang __mtime__ 2018/4/21 """ from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait …

制作系统盘

老毛桃&#xff08;LaoMaoTao&#xff09; 制作启动盘 第一步.进入官方网站下载我们的老毛桃 下载老毛桃U盘制作工具后&#xff0c;双击打开老毛桃的运行程序。 打开老毛桃U盘制作工具&#xff0c;插入需要制作的U盘&#xff08;如图所示U盘winpe系统制作界面&#xff09;。…
最新文章