LeetCode刷题复盘笔记—一文搞懂完全背包之377. 组合总和 Ⅳ问题(动态规划系列第十二篇)

news2024/12/26 21:25:04

今日主要总结一下动态规划完全背包的一道题目,377. 组合总和 Ⅳ

题目:377. 组合总和 Ⅳ

Leetcode题目地址
题目描述:
给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。

题目数据保证答案符合 32 位整数范围。

示例 1:

输入:nums = [1,2,3], target = 4
输出:7
解释:
所有可能的组合为:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
请注意,顺序不同的序列被视作不同的组合。
示例 2:

输入:nums = [9], target = 3
输出:0

提示:

1 <= nums.length <= 200
1 <= nums[i] <= 1000
nums 中的所有元素 互不相同
1 <= target <= 1000

本题重难点

这是一道典型的背包问题,本题给定的数组里面的元素可以重复取,所以这是一个完全背包。

本题题目描述说是求组合,但又说是可以元素相同顺序不同的组合算两个组合,其实就是求排列!

弄清什么是组合,什么是排列很重要。

组合不强调顺序,(1,5)和(5,1)是同一个组合。

排列强调顺序,(1,5)和(5,1)是两个不同的排列。

但其本质是本题求的是排列总和,而且仅仅是求排列总和的个数,并不是把所有的排列都列出来。

如果本题要把排列都列出来的话,只能使用回溯算法爆搜。

动规五部曲分析如下:

  1. 确定dp数组以及下标的含义
    dp[i]: 凑成目标正整数为i的排列个数为dp[i]

  2. 确定递推公式
    dp[i](考虑nums[j])可以由 dp[i - nums[j]](不考虑nums[j]) 推导出来。
    因为只要得到nums[j],排列个数dp[i - nums[j]],就是dp[i]的一部分。
    在一文搞懂0 - 1背包之494. 目标和问题和 一文搞懂完全背包之518. 零钱兑换 II问题中我们已经讲过了,求装满背包有几种方法,递推公式一般都是dp[i] += dp[i - nums[j]];
    本题也一样。

  3. dp数组如何初始化
    因为递推公式dp[i] += dp[i - nums[j]]的缘故,dp[0]要初始化为1,这样递归其他dp[i]的时候才会有数值基础。
    至于dp[0] = 1 有没有意义呢?
    其实没有意义,所以我也不去强行解释它的意义了,因为题目中也说了:给定目标值是正整数! 所以dp[0] = 1是没有意义的,仅仅是为了推导递推公式。
    至于非0下标的dp[i]应该初始为多少呢?
    初始化为0,这样才不会影响dp[i]累加所有的dp[i - nums[j]]。

  4. 确定遍历顺序
    个数可以不限使用,说明这是一个完全背包。
    得到的集合是排列,说明需要考虑元素之间的顺序。
    本题要求的是排列,那么这个for循环嵌套的顺序可以有说法了。
    在一文搞懂完全背包之518. 零钱兑换 II问题中就已经讲过了。
    如果求组合数就是外层for循环遍历物品,内层for遍历背包。
    如果求排列数就是外层for遍历背包,内层for循环遍历物品。
    如果把遍历nums(物品)放在外循环,遍历target的作为内循环的话,举一个例子:计算dp[4]的时候,结果集只有 {1,3} 这样的集合,不会有{3,1}这样的集合,因为nums遍历放在外层,3只能出现在1后面!
    所以本题遍历顺序最终遍历顺序:target(背包)放在外循环,将nums(物品)放在内循环,内循环从前到后遍历。

  5. 举例来推导dp数组

我们再来用示例中的例子推导一下: 在这里插入图片描述:
在这里插入图片描述

C++代码

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

C++测试用例有两个数相加超过int的数据,所以需要在if里加上
dp[i] < INT_MAX - dp[i - num]。


总结

动态规划
英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。
动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的

对于动态规划问题,可以拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

这篇文章主要总结了一些动态规划解决518. 零钱兑换 II问题,依然是使用动规五部曲,做每道动态规划题目这五步都要弄清楚才能更清楚的理解题目!

求装满背包有几种方法,递归公式都是一样的,没有什么差别,我们在一文搞懂0 - 1背包之494. 目标和问题中就已经讲过了

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

本题的难点主要在于遍历顺序!

在求装满背包有几种方案的时候,认清遍历顺序是非常关键的。

  • 如果求组合数就是外层for循环遍历物品,内层for遍历背包。(也就是0-1背包一维dp数组常用写法)

  • 如果求排列数就是外层for遍历背包,内层for循环遍历物品。

本题与一文搞懂完全背包之518. 零钱兑换 II问题就是一个鲜明的对比,一个是求排列,一个是求组合,遍历顺序完全不同。

欢迎大家关注本人公众号:编程复盘与思考随笔

(关注后可以免费获得本人在csdn发布的资源源码)

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

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

相关文章

[附源码]计算机毕业设计基于web的羽毛球管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Python软件编程等级考试一级——20220915

Python软件编程等级考试一级——20220915理论单选题判断题实操第一题第二题理论 单选题 1、表达式len(“学史明理增信 &#xff0c;读史终生受益”) > len(" reading history will benefit you ")的结果是&#xff1f; A、0 B、True C、False D、1 2、表达…

SLMi333国内首款兼容光耦带DESAT保护功能的隔离式栅极驱动器

SLMi333国内首款兼容光耦带DESAT保护功能的隔离式栅极驱动器,内置快速去饱和&#xff08;DESAT&#xff09;故障检测功能&#xff0c;米勒钳位功能&#xff0c;漏极开路故障反馈&#xff0c;软关断功能以及可选择的自恢复模式&#xff0c;兼容光耦隔离驱动器&#xff0c;一款高…

安装mongodb6

一、安装mongodb6.0.2 1.官网下载社区版 https://www.mongodb.com/ 2.双击下载的文件&#xff0c;按步骤安装 选择custom 自定义安装 改一下安装地址&#xff0c;路径最好不要带空格 Install MongoD as a Service 作为服务方式安装 Run the service as Network Service…

SuperMap iClient for Leaflet对EPSG:4509图加载滑动查询

作者&#xff1a;John SuperMap iClient for Leaflet对EPSG:4509地图加载&滑动查询 在WebGIS开发使用中&#xff0c;我们会遇到地图显示不了&#xff0c;以及查询到数据显示不出的问题&#xff0c;因此本文就以EPSG:4509为例介绍该坐标系地图加载和查询。 1、EPSG:4509地图…

数据分析案例:基于水色图像的水质识别

大数据分析课程、大数据分析班、大数据案例等&#xff0c;围绕大数据展开讲解。 数据分析案例&#xff1a;基于水色图像的水质识别&#xff0c;通过学习本案例&#xff0c;可以掌握图像切割、特征提取、模型构建和模型评价的主要方法和技能&#xff0c;并为后续相关课程学习及将…

蚂蚁面试官:Zookeeper 的选举流程是怎样的?我当场懵逼了

​ 编辑切换为居中 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 面试经常会遇到面试官问 Zookeeper 的选举原理&#xff0c;我心想&#xff0c;问这些有啥用吗&#xff1f;又不要我造火箭&#xff01; 每次面试也只知道个大概&#xff0c;并没有深究…

分布式电源接入对配电网影响的研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

vue3 + element 从0到1搭建前端基础框架

一、框架搭建 框架代码 个人博客 往往从0到1开发项目时发觉无从下手&#xff0c;或者很可能一步一个坑&#xff0c;因为大多基础框架公司已经搭建完毕的&#xff0c;新加入的成员也都是在此基础上进行功能模块的拓展。网上也鲜有详尽的全流程参考&#xff0c;多是某个局部功能的…

【Vue】webpack的基本使用

✍️ 作者简介: 前端新手学习中。 &#x1f482; 作者主页: 作者主页查看更多前端教学 &#x1f393; 专栏分享&#xff1a;css重难点教学 Node.js教学 从头开始学习 ajax学习 文章目录webpack的学习目标前端工程化 小白眼中的前端开发 vs 实际的前端开发 什么是前端工程…

CISP考试大纲/范围

CISP考试主要是考CISP知识体系大纲&#xff0c;分别为信息安全保障、信息安全技术、信息安全管理、信息安全工程和信息安全标准法规这五大知识类&#xff0c;每个知识类根据其逻辑划分为多个知识体&#xff0c;每个知识体包含多个知识域&#xff0c;每个知识域由一个或多个知识…

Java项目:SSM失物招领管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 主要功能包括&#xff1a; 用户发布失物&#xff0c;或者招领失物&#xff0c;管理员对用户&#xff0c;失物信息进行增删改查。 环境需要 1…

新课程教学杂志新课程教学杂志社新课程教学编辑部2022年第19期目录

核心素养 核心素养视域下的历史教学设计——以“清朝君主专制的强化”为例 王威; 1-3 新中考背景下文本分析能力与核心素养的培育 黄嫄; 4-5《新课程教学》投稿&#xff1a;cn7kantougao163.com 基于核心素养的物理教学评价改良 李红; 6-7 初中语文综合性学习的…

Metabase学习教程:系统管理-6

Metabase可扩展性 扩展Metabase以支持更多人和数据库的最佳实践。 Metabase是一个可扩展的、经过实战的软件&#xff0c;被成千上万的公司用来提供高质量的自助服务分析。它通过水平扩展支持高可用性&#xff0c;而且它是开箱即用的高效工具&#xff1a;一台拥有4gb内存的单核…

vue.js axios 数据不刷新

getServerList(){axios.get(/server/showList).then(function(response){this.servers response.data // 不刷新console.log(response.data)}).catch(function (error) {console.log(error);}); } 打印this&#xff1a;this不是vue对象修改为&#xff1a;getServerList(){axi…

Mysql各种缓冲区的功能及之间的联系

buffer poolmysql数据存放在磁盘里面&#xff0c;如果每次查询都直接从磁盘里面查询&#xff0c;会影响性能&#xff0c;因此需要内存态缓存池。另外缓存池的淘汰机制不是基础LRU&#xff0c;而是是改进版LRU&#xff0c;防止大量临时缓存挤出热点数据。buffer pool读缓存分为老…

代码随想录算法训练营第五十三天| LeetCode1143. 最长公共子序列、LeetCode1035. 不相交的线、LeetCode53. 最大子数组和

一、LeetCode1143. 最长公共子序列 1&#xff1a;题目描述&#xff08;1143. 最长公共子序列&#xff09; 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一…

Leetcode 1687. 从仓库到码头运输箱子 [四种解法] 动态规划 从朴素出发详细剖析优化步骤

你有一辆货运卡车&#xff0c;你需要用这一辆车把一些箱子从仓库运送到码头。这辆卡车每次运输有 箱子数目的限制 和 总重量的限制 。给你一个箱子数组 boxes 和三个整数 portsCount, maxBoxes 和 maxWeight &#xff0c;其中 boxes[i] [ports​​i​, weighti] 。ports​​i …

网页制作课作业基于HTML+CSS+JavaScript+jquery仿慕课网教学培训网站设计实例 企业网站制作

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

【强化学习论文】离线元强化学习中基于对比学习的稳定表示

离线元强化学习中基于对比学习的稳定表示 最近几年来深度强化学习在算法上有很多进展&#xff0c;已初步用在很多场景中。目前深度强化学习有两个重要的问题&#xff1a;数据利用问题&#xff0c;泛化能力。深度强化学习通常要与环境进行大量的交互&#xff0c;通常效率较低&am…