LeetCode 518.零钱兑换II 动态规划 + 完全背包 + 组合数

news2024/11/15 21:49:45

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。

假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带符号整数。

示例 1:

输入:amount = 5, coins = [1, 2, 5]
输出:4
解释:有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

示例 2:

输入:amount = 3, coins = [2]
输出:0
解释:只用面额 2 的硬币不能凑成总金额 3 。

示例 3:

输入:amount = 10, coins = [10] 
输出:1

>>思路和分析

  • ① 钱币数量不限,可以知道这是一个完全背包的问题;
  • ② 与纯完全背包式凑成背包最大价值是多少,而本题是要求凑成总金额的物品组合个数!

注意题目描述中是凑成总金额的硬币组合数,为什么强调是组合数呢?

例如示例一:

        5 = 2 + 2 + 1 

        5 = 2 + 1 + 2

这是一种组合,都是 2 2 1。如果问的是排列数,上面就是两种排列了。

注意:组合不强调元素之间的顺序,排列强调元素之间的顺序

>>动规五部曲

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

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

2.确定递推公式

  •  dp[j] 就是所有的 dp[j - coins[i]] (考虑 coins[i] 的情况)相加
  •  所以递推公式:dp[j] += dp[j - coins[i]];

0-1背包题目有这篇LeetCode 494.目标和中讲解了,求装满背包有几种方法,公式都是:

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

3.dp数组初始化

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

下标非0的dp[j]初始化为0,这样累计加dp[j - coins[i]]的时候才不会影响真正的 dp[j]

dp[0] = 1 还说明了一种情况:如果正好选了coins[i]后,也就是 j - coins[i] == 0的情况表示这个硬币刚好能选,此时 dp[0] 为1 表示只选coins[i]存在这样的一种选法

4.确定遍历顺序

  • 方式一:先遍历物品再遍历背包
  • 方式二:先遍历背包再遍历物品

在纯完全背包中,先遍历物品再遍历背包,还是先遍历背包再遍历物品,两者都可以!

本题就不行了!因为纯完全背包求得装满背包的最大价值是多少,和凑成总和的元素有没有顺序是没有关系的,即:有顺序也行,没顺序也行!

但在本题中要求凑合总和的组合数,元素之间明确要求没有顺序的。所以只能是方式一这种遍历顺序,那为什么不能是方式二呢?

对于方式一在完全背包中:外层for 循环遍历物品(钱币),内层for遍历背包(金钱总额)的情况

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

假设:coins[0] = 1,coins[1] = 5

那么就是先把1加入计算,再把5加入计算,得到的只有{1,5}这种情况,是不会出现{5,1}这种情况的,所以这种遍历顺序中dp[j]里计算的是组合数!

对于方式二在完全背包中:外层for遍历背包(金钱总额),内层for 循环遍历物品(钱币)的情况

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]];
    }
}

背包容量的每一个值,都是经过1 和 5的计算,包含了 {1,5} 和 {5,1}两种情况。此时dp[j]里算出来的就是排列数!

5.举例推导dp数组

输入:amount = 5,coins = [1,2,5],dp状态图如下:

dp[amout]为最终结果

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        vector<int> dp(amount + 1, 0);
        dp[0] = 1;
        for (int i = 0; i < coins.size(); i++) { // 遍历物品
            for (int j = coins[i]; j <= amount; j++) { // 遍历背包
                dp[j] += dp[j - coins[i]];
            }
        }
        return dp[amount];
    }
};
  • 时间复杂度:O(mn),其中 m 是 amount,n是coins的长度
  • 空间复杂度:O(m)

【总结】

本题的递推公式,在 494.目标和 中已经做了详细讲解,而本题的难点主要在于遍历顺序!

  • 在求装满背包有几种方案的时候,确定遍历顺序是非常关键的;
  • 如果求组合数,那就是外层for循环遍历物品,内层for循环遍历背包
  • 如果求排列数,那就是外层for循环遍历背包,内层for循环遍历物品

来自代码随想录的课堂截图:

参考文章和视频:

代码随想录 (programmercarl.com)

动态规划之完全背包,装满背包有多少种方法?组合与排列有讲究!| LeetCode:518.零钱兑换II_哔哩哔哩_bilibili

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

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

相关文章

DevOps持续集成与交付

概述 Jenkins是一个支持容器化部署的、使用Java运行环境的开源软件&#xff0c;使用Jenkins平台可以定制化不同的流程与任务、以自动化的机制支持DevOps领域中的CI与CD&#xff0c;在软件开发与运维的流程中自动化地执行软件工程项目的编译、构建、打包、测试、发布以及部署&a…

FileManager/本地文件增删改查, Cache/图像缓存处理 的操作

1. FileManager 本地文件管理器&#xff0c;增删改查文件 1.1 实现 // 本地文件管理器 class LocalFileManager{// 单例模式static let instance LocalFileManager()let folderName "MyApp_Images"init() {createFolderIfNeeded()}// 创建特定应用的文件夹func cr…

在英文电脑系统中,中文显示??????

如果操作系统是英文的&#xff0c;那么无论是在cmd界面&#xff0c;还是在Visual Studio的调试界面&#xff0c;中文显示都是一串问号??????? 这是因为在英文系统中&#xff0c;Console 的默认代码页是 437(OEM -United States)&#xff0c;不支持中文输入输出&#xff…

照片后期处理软件DxO FilmPack 6 mac中文说明

DxO FilmPack 6 for Mac是一款照片后期处理软件。它可以模拟超过60种著名胶片品牌和类型的色彩和颗粒感&#xff0c;使照片具有复古、艺术和时尚风格。 ​DxO FilmPack 6 mac支持RAW和JPG格式的照片&#xff0c;并提供丰富的调整选项&#xff0c;如亮度、对比度、曝光、阴影和高…

十六.镜头知识之工业镜头的质量判断因素

十六.镜头知识之工业镜头的质量判断因素 文章目录 十六.镜头知识之工业镜头的质量判断因素1.分辨率(Resolution)2.明锐度(Acutance)3.景深(DOF)&#xff1a;4. 最大相对孔径与光圈系数5.工业镜头各参数间的相互影响关系5.1.焦距大小的影响情况5.2.光圈大小的影响情况5.3.像场中…

【Java 进阶篇】深入理解SQL查询语言(DQL)

SQL&#xff08;Structured Query Language&#xff09;是一种用于管理关系型数据库的强大编程语言。它提供了各种命令和语句&#xff0c;用于执行各种操作&#xff0c;包括数据查询、插入、更新和删除。本文将深入探讨SQL查询语言&#xff08;DQL&#xff09;&#xff0c;它是…

Bootstrap的弹性盒子布局学习笔记

Bootstrap的弹性盒子布局学习笔记 目录 01-综述02-利用类d-flex与类d-inline-flex将容器定义为弹性盒子03-对弹性容器的的元素在水平方向上进行排列顺序设置03-对弹性容器的的元素在垂直方向上进行排列顺序设置04-弹性盒子内所有元素在主轴方向上的对齐方式05-1-弹性盒子内各行…

myArm 全新七轴桌面型机械臂

引言 在不断演进的科技世界中&#xff0c;我们始终追求创新和卓越&#xff0c;以满足客户的需求并超越他们的期望。今天&#xff0c;我们很高兴地宣布我们的最新产品——myArm 300 Pi&#xff0c;一款七轴的桌面型机械臂。这款产品的独特之处在于其灵活性和可编程性&#xff0c…

16. Seata 分布式事务

Spring Cloud 微服务系列文章&#xff0c;点击上方合集↑ 1. 简介 Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。 事务是保障一系列操作要么都成功&#xff0c;要么都失败。就比如转账&#xff1a;A转账100元给B&#xff0…

sentinel-dashboard-1.8.0.jar开机自启动脚本

启动阿里巴巴的流控组件控制面板需要运行一个jar包&#xff0c;通常需要运行如下命令&#xff1a; java -server -Xms4G -Xmx4G -Dserver.port8080 -Dcsp.sentinel.dashboard.server127.0.0.1:8080 -Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.8.0.jar &…

如何评估测试用例的优先级?

评估测试用例的优先级&#xff0c;有助于我们及早发现和解决可能对系统稳定性和功能完整性产生重大影响的问题&#xff0c;助于提高测试质量&#xff0c;提高用户满意度。 如果没有做好测试用例的优先级评估&#xff0c;往往容易造成对系统关键功能和高风险场景测试的忽略&…

STM32定时器

目录 基本定时器结构框图 通用定时器结构框图 高级定时器结构框图 ​编辑TIMx时基单元 定时工作原理 影子寄存器 ​编辑 定时器中断基本结构 定时器计时中断 定时器外部中断 输出比较 OC 输出比较模式 PWM基本结构 输出比较常用函数 使用PWM来驱动舵机 输入捕…

NAS文件的名称或路径过长导致文件同步被挂起

将文件复制到群晖设备时遇到文件名长度限制问题&#xff0c;NTFS文件系统&#xff08;通过Samba等方式在群晖上使用&#xff09;: 在Windows系统上广泛使用的NTFS文件系统也支持较长的文件名&#xff0c;最大长度为255个字符。然而&#xff0c;要注意的是&#xff0c;使用Samba…

如何找回回收站删除的文件?文件恢复,3个方法!

“求助求助&#xff01;回收站里面删除的文件还能恢复吗&#xff1f;在清理电脑内存的时候一不小心把回收站清空了&#xff0c;现在不知道如何是好&#xff0c;请大家帮帮我&#xff01;” 电脑回收站里的文件清空了就是被永久删除了吗&#xff1f;如果误删了回收站里的文件还有…

成都优优聚是做美团餐饮代运营的吗?

成都优优聚公司是一家专注于美团代运营的企业&#xff0c;致力于为餐饮业主提供全方位的服务和解决方案。在如今的互联网时代&#xff0c;美团已经成为了许多餐饮业主不可或缺的平台之一&#xff0c;但是对于一些传统的餐饮业主来说&#xff0c;运营美团平台可能并不容易&#…

直播软件开发趋势揭秘:抓住行业热点实现爆发增长

直播软件开发者们正迎来一个前所未有的繁荣时期。随着社交媒体的普及和5G网络的迅猛发展&#xff0c;直播行业吸引了越来越多的用户&#xff0c;创造了巨大的商机。本文将揭示最新的直播软件开发趋势&#xff0c;帮助你抓住这个行业的热点&#xff0c;实现爆发性的增长。 关键…

【广州华锐互动】屠宰场生猪检疫VR模拟演练系统

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术在各个领域的应用越来越广泛。在教育领域&#xff0c;VR技术也为学生提供了更加真实和沉浸式的学习体验。屠宰场生猪检疫VR模拟演练系统由VR公司广州华锐互动所开发&#xff0c;作为一种新型的教学方式&a…

黑马VUE3视频笔记

目录 一、使用create-vue创建项目 二、setup选项 三、reactive和ref函数 1.reactive() 2.ref() 三、computed 四、watch ​五、生命周期函数 六、父传子、子传父 父传子defineProps 子传父defineEmits 七、模板引用 ref defineExpose 八、跨层传递普通数据 prov…

正交对角化,奇异值分解

与普通矩阵对角化不同的是&#xff0c;正交对角化是使用正交矩阵对角化&#xff0c;正交矩阵是每列向量都是单位向量&#xff0c;正交矩阵*它的转置就是单位矩阵 与普通矩阵对角化一样&#xff0c;正交对角化的结果也是由特征值组成的对角矩阵 本质还是特征向量对原矩阵的拉伸…

Go 里的超时控制

前言 日常开发中我们大概率会遇到超时控制的场景&#xff0c;比如一个批量耗时任务、网络请求等&#xff1b;一个良好的超时控制可以有效的避免一些问题&#xff08;比如 goroutine 泄露、资源不释放等&#xff09;。 Timer 在 go 中实现超时控制的方法非常简单&#xff0c;…