代码随想录算法训练营第四十四天|完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ

代码随想录 (programmercarl.com)

完全背包

完全背包的物品数量不受限制(正序遍历物品),0-1背包每个物品只能使用一次(倒序遍历背包)

完全背包两个for循环可以颠倒顺序,一维0-1背包问题只能先遍历物品再遍历背包。

518. 零钱兑换 II

类似于前面0-1背包的494.目标和问题

1.确定dp数组以及下标的含义

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

2.确定递推公式

有多少种方法用的都是这个递推公式:dp[j] += dp[j - coins[i]];

3.dp数组如何初始化

dp[0] = 1是 递归公式的基础,如果dp[0] = 0 的话,后面所有推导出来的值都是0了。

后台测试数据是默认,amount = 0 的情况,组合数为1。

4.确定遍历顺序

不同于纯完全背包问题,遍历顺序两个for循环可以调换顺序,此处不可以。

纯完全背包求得装满背包的最大价值是多少,和凑成总和的元素有没有顺序没关系,即:有顺序也行,没有顺序也行。而本题要求凑成总和的组合数,元素之间明确要求没有顺序。所以纯完全背包是能凑成总和就行,不用管怎么凑的。

但是本题是求凑出来的方案个数,且每个方案个数是为组合数。

所以本题就需要注意遍历顺序,以下分情况讨论,以amount=5和coins=[1,2,5]为例:

1)先遍历物品再遍历背包:

物品按照遍历顺序出现{1,2},不会出现{1,2}{2,1}同时出现的情况,即得出的是组合数

for (int i = 0; i < coins.size(); i++) { // 遍历物品for (int j = coins[i]; j <= amount; j++) { // 遍历背包容量dp[j] += dp[j - coins[i]];}
}

2)先遍历背包再遍历物品:

遍历背包后物品每次都会再重新遍历一遍,会出现{1,2}{2,1}同时出现的情况,即得出的是排列数

for (int j = 0; j <= amount; j++) { // 遍历背包容量for (int i = 0; i < coins.size(); i++) { // 遍历物品if (j - coins[i] >= 0) dp[j] += dp[j - coins[i]];}
}

打印结果:

dp[j]j = 012345
i = 0100000
1112

3

i = 0:

dp[3] += dp[3-1]==>dp[3] = 2==>[1,1,1][1,2]

i = 1:

dp[3] += dp[3-2]==>dp[3] = 2 + 1 = 3==>[2,1]

此处j = 3的情况中,就出现了[1,1,1][1,2][2,1]

所以为排列数,不符合题意

2
class Solution {public int change(int amount, int[] coins) {int[] dp = new int[amount + 1];dp[0] = 1;for (int i = 0; i < coins.length; i++) {for (int j = coins[i]; j <= amount; j++) {
//注意j的起始大小,回顾dp[j]含义可知,j为背包容量,
//要确保其大于物品的重量,即需要从coins[i]开始遍历,而不是coins[0]dp[j] += dp[j - coins[i]];}}return dp[amount];}
}

注意j的起始大小,回顾dp[j]含义可知,j为背包容量,要确保其大于物品的重量,即需要从coins[i]开始遍历,而不是coins[0]。

377. 组合总和 Ⅳ  

1.确定dp数组以及下标的含义

dp[i]:凑成目标正整数为i的排列个数为dp[i]

2.确定递推公式

有多少种方法用的都是这个递推公式:dp[j] += dp[j - coins[i]];

3.dp数组如何初始化

题目中说给定目标值是正整数, 所以dp[0] = 1是没有意义的,此处的初始化仅仅是为了推导递推公式。

4.确定遍历顺序

求的是排列数,所以选择先遍历背包再遍历物品的顺序。

如果求组合数就是先物品再背包,如果求排列数就是先背包再物品。

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

【拓展爬楼梯】

原始==一步只能爬1,2个台阶;进阶==一步可以爬m个台阶,到楼顶有多少种爬楼方式,代码和本题一致,求解排列数。

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

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

相关文章

Leetcode 509 斐波那契数

题意理解&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。 其满足递推公式&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n > 1 目标&#xff1a;求…

华为鸿蒙(HarmonyOS)介绍

华为鸿蒙&#xff08;HarmonyOS&#xff09;介绍 华为鸿蒙&#xff08;HarmonyOS&#xff09;是一款由华为自主研发的操作系统&#xff0c;旨在为各种智能设备提供一种统一、高效、安全的解决方案。鸿蒙系统基于微内核架构&#xff0c;可以应用于多种类型的设备&#xff0c;鸿…

服务器感染了.[steloj@mailfence.com].steloj勒索病毒,如何确保数据文件完整恢复?

导言&#xff1a; .steloj勒索病毒&#xff0c;如今已是网络安全领域的一颗新星。这种病毒采用高度复杂的加密算法&#xff0c;将用户文件锁定&#xff0c;迫使受害者支付赎金以获得解密密钥。本文将深入剖析.steloj勒索病毒&#xff0c;使读者对这一威胁有更全面的认识。如不…

快速上手makefile自动化构建工具

makefile自动化构建工具 文章目录 makefile自动化构建工具 makefile背景 简单认识makefile 依赖关系与依赖方法 生成项目 清理项目 ACM时间 语法补充 .PHONY修饰 特殊符号替换 Makefile的推导过程 总结 前言&#xff1a; 在windows下&#xff0c;很多东西都是编译器直接帮你做…

06、docker 安装mysql8

Docker 安装 MySQL8 下载mysql8的镜像 docker pull mysql:8.0.32启动镜像 docker run -p 3307:3306 --name mysql8 -e MYSQL_ROOT_PASSWORD123456 -d mysql:8.0.32配置挂载 创建挂载目录 mkdir -p /docker/mysql8.0.32/copy配置文件到创建的目录下 docker cp mysql:/etc/mysql…

docker学习笔记01-安装docker

1.Docker的概述 用Go语言实现的开源应用项目&#xff08;container&#xff09;&#xff1b;克服操作系统的笨重&#xff1b;快速部署&#xff1b;只隔离应用程序的运行时环境但容器之间可以共享同一个操作系统&#xff1b;Docker通过隔离机制&#xff0c;每个容器间是互相隔离…

计算机基础——原、反、补码与位运算

一、原、反、补码 一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的&#xff0c;在计算机用一个数的最高位存放符号, 正数为0, 负数为1。 在介绍位运算符前先了解一下原码、反码和补码。 计算机中的有符号数有三种表示方法&#xff0c;即原码、反码…

Kafka学习笔记1(千峰教育)

Kafka学习笔记1&#xff08;千峰教育&#xff09; 一、为什么使用消息队列1.使用同步的通信方式来解决多个服务之间的通信2.使用异步的通信方式 二、消息队列的流派1.有broker2.无broker 三、Kafka的基本知识1.Kafk2a的安装2.Kafka中的一些基本概念3.创建topic4.发送消息5.消费…

通过讯飞 API 接口用 Vue 实现实时语音转写

通过讯飞 API 接口用 Vue 实现实时语音转写 项目地址 前言 本项目中实时语音能够转写的最大时间为 60 s&#xff0c; 这个数据也是由 API 提供方给限制掉的 为什么我会需要这个点击按钮以后能够实现实时语音的转写呢&#xff0c;因为被课程所迫&#xff0c;选了这个方向就必…

百度每天20%新增代码由AI生成,Comate SaaS服务8000家客户 采纳率超40%

12月28日&#xff0c;由深度学习技术及应用国家工程研究中心主办的WAVE SUMMIT深度学习开发者大会2023在北京召开。百度首席技术官、深度学习技术及应用国家工程研究中心主任王海峰现场公布了飞桨文心五载十届最新生态成果&#xff0c;文心一言最新用户规模破1亿&#xff0c;截…

Leetcode 763 划分字母区间

题意理解&#xff1a; 要把这个字符串划分为尽可能多的片段&#xff0c;同一字母最多出现在一个片段中。 注意&#xff0c;划分结果需要满足&#xff1a;将所有划分结果按顺序连接&#xff0c;得到的字符串仍然是 s 。 返回一个表示每个字符串片段的长度的列表。 输入&#xff…

vue解决执行打包之后打开页面空白问题

如果我们在执行了build打包命令之后&#xff0c;打开dist目录下的html文件打开页面空白&#xff0c;有几个常见的问题和解决方法 检查控制台报错&#xff1a; 打开浏览器的开发者工具&#xff0c;查看控制台&#xff08;Console&#xff09;中是否有报错信息。报错信息通常能够…

【头歌实训】kafka-入门篇

文章目录 第1关&#xff1a;kafka - 初体验任务描述相关知识Kafka 简述Kafka 应用场景Kafka 架构组件kafka 常用命令 编程要求测试说明答案代码 第2关&#xff1a;生产者 &#xff08;Producer &#xff09; - 简单模式任务描述相关知识Producer 简单模式Producer 的开发步骤Ka…

JavaScript解构赋值

解构赋值是一种方便的 JavaScript 语法&#xff0c;它允许从数组和对象中快速提取和赋值变量。通过解构赋值&#xff0c;你可以在一个语句中将值从数组或对象中解构出来并赋给多个变量。 数组解构赋值&#xff1a; 数组解构赋值允许你从数组中提取值&#xff0c;并将它们赋给命…

VS Code 运行 Python

介绍 Python&#xff1a; 是一种强大的编程语言&#xff0c;具有广泛的应用领域&#xff0c;可以用于开发 Web 应用、数据分析、人工智能、科学计算等多种领域。 VS Code&#xff1a; 是由微软开发的免费开源代码编辑器&#xff0c;可以在多个平台上运行。具有丰富的扩展功能…

每日一题--------求数字的每⼀位之和

大家好今天的每日一题又来了&#xff0c;有啥不对的请在评论区留言哦 文章目录 目录 文章目录 求数字的每⼀位之和 题⽬描述&#xff1a; 输⼊⼀个整数m&#xff0c;求这个整数m的每⼀位之和&#xff0c;并打印。 一、解题思路 我们可以通过不断获取该整数的个位数&#xff0c…

Python+OpenCV 零基础学习笔记(4-5):计算机图形基础+Python相对文件路径+OpenCV图像+OpenCV视频

文章目录 相关链接运行环境前言计算机图形OpenCV简单使用图形读取文件读取可能会出现的问题&#xff1a;路径不对解决方案其它路径问题解决方案 图像显示保存OpenCV视频视频素材如何获取&#xff1f;简单视频读取 相关链接 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 …

python抽象基类之_subclasshook_方法

Python的鸭子特性&#xff08;duck typing&#xff09; Python中自定义的类只要实现了某种特殊的协议&#xff0c;就能赋予那种行为&#xff0c;举一个简单的例子&#xff1a; class A:def __len__(self):return 0 a A() print(len(a)) 如上所示&#xff0c;自己定义了一个类…

Synchronized、ReentrantLock 和 ReadWriteLock底层原理

Synchronized 底层原理 1. JVM 层面的实现 synchronized 是 Java 中的一个关键字&#xff0c;它提供了一种简单的策略来实现线程同步。在 JVM 层面&#xff0c;synchronized 可以依赖于对象内部的监视器锁&#xff08;monitor lock&#xff09;来实现同步。 锁的获取与释放&a…

GB/T 41480-2022 门和卷帘的防烟性能

门和卷帘的防烟是指在指定的试验温度、压差条件下&#xff0c;烟气从一侧泄露到另一侧的烟气泄露速率。 GB/T 41480-2022 门和卷帘的防烟性能样品要求 门或卷帘试件结构为非对称时&#xff0c;应对结构相对薄弱的一面进行测试&#xff0c;其中常温试验测试一个试件&#xff0…