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

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

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

完全背包

题目链接:题目页面 (kamacoder.com)

解释一、01背包 一维 :为什么要倒序遍历背包

首先要明白二维数组的递推过程,然后才能看懂二维变一维的过程。

假设目前有背包容量为10,可以装的最大价值, 记为g(10)。

即将进来的物品重量为6。价值为9。
那么此时可以选择装该物品或者不装该物品。

如果不装该物品,显然背包容量无变化,这里对应二维数组,其实就是取该格子上方的格子复制下来,就是所说的滚动下来,直接g【10】 = g【10】,这两个g【10】要搞清楚,右边的g【10】是上一轮记录的,也就是对应二维数组里上一层的值,而左边是新的g【10】,也就是对应二维数组里下一层的值。

如果装该物品,则背包容量= g(10-6) = g(4) + 9 ,也就是 g(10) = g(4) + 6 ,这里的6显然就是新进来的物品的价值,g(10)就是新记录的,对应二维数组里下一层的值,而这里的g(4)是对应二维数组里上一层的值,通俗的来讲:你要找到上一层也就是上一状态下 背包容量为4时的能装的最大价值,用它来更新下一层的这一状态,也就是加入了价值为9的物品的新状态。

这时候如果是正序遍历会怎么样? g(10) = g(4) + 6 ,这个式子里的g(4)就不再是上一层的了,因为你是正序啊,g(4) 比g(10)提前更新,那么此时程序已经没法读取到上一层的g(4)了,新更新的下一层的g(4)覆盖掉了,这里也就是为啥有题解说一件物品被拿了两次的原因

解释二、01背包到底先遍历物品还是先遍历背包呢?

其实在二维的时候,即使是先遍历背包重量,再遍历物品重量,你真的画图的时候会发现,永远的数据来源,依旧还是max(不放,放)= max(正上方的值,左上角的值)。

那你在一维的时候,如果先遍历背包容量的话:

如果你还是从左到右地遍历背包容量:一样会造成重复添加;

如果你从右到左地遍历背包容量:相当于你的计算顺序是先竖着写完第四列,再竖着写完第三列,再竖着写完第二列。。。但你写第四列的时候,第三列全部都是空的,左边是没有数据的,你永远只在累加正上方的数。而如果你是先遍历物品再遍历背包,你的填空顺序是,先写第一行(从右往左写),再写第二行的时候,你的左边是有数字的。。。

那你可能想问,我能不能做一个竖着的表格更新呢?其实没有帮助的,你只要先一股脑地竖着算,你永远没法利用起左边格子的数字——无法利用之前格子的数,那就不是动态规划了

解释三、为什么完全背包可以颠倒物品和背包的遍历顺序?

请想像一下 01背包的二维dp数组图像 和 完全背包的二维dp数组图像

01背包二维数组dp[i] [j]只取决于其左上角的值,所以 使用二维数组时可以从对物品和背包数组进行正序遍历,且先物品还是先背包可以颠倒

01背包一维数组dp[j] 因为

背包必须要倒序遍历(参考上面解释一、01背包 一维 :为什么要倒序遍历背包

如果遍历背包容量放在上一层,那么每个dp[j]就只会放入一个物品,即:背包里只放入了一个物品(解释二

所以要先物品后背包

完全背包其dp[j]完全取决于

// 先遍历物品再遍历背包
import java.util.*;public class Main {public static void main (String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int V = sc.nextInt();int[] weights = new int[N];int[] values = new int[N];for(int i = 0; i < N; ++i) {weights[i] = sc.nextInt();values[i] = sc.nextInt();}int[] dp = new int[V + 1];for(int i = 0; i < N; ++i) {for(int j = weights[i]; j <= V; ++j) {dp[j] = Math.max(dp[j], dp[j - weights[i]] + values[i]);}}System.out.println(dp[V]);}
}
// 先遍历背包再遍历物品
import java.util.*;public class Main {public static void main (String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int V = sc.nextInt();int[] weights = new int[N];int[] values = new int[N];for(int i = 0; i < N; ++i) {weights[i] = sc.nextInt();values[i] = sc.nextInt();}int[] dp = new int[V + 1];for(int j = 1; j <= V; ++j) {for(int i = 0; i < N; ++i) {if(j >= weights[i]) {dp[j] = Math.max(dp[j], dp[j - weights[i]] + values[i]);}                }}System.out.println(dp[V]);}
}

零钱兑换 II

题目链接:518. 零钱兑换 II - 力扣(LeetCode)

这道题就是 494. 目标和 - 力扣(LeetCode)的完全背包版本

如果求组合数就是外层for循环遍历物品,内层for遍历背包

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

class Solution {public int change(int amount, int[] coins) {//  硬币数量不限 -> 完全背包// dp[j] 表示:填满j(包括j)这么大容积的包,有dp[j]种方法int[] dp = new int[amount + 1];// dp[0] = 1是 递归公式的基础。如果dp[0] = 0 的话,后面所有推导出来的值都是0了。dp[0] = 1;// 因为纯完全背包求得装满背包的最大价值是多少,和凑成总和的元素有没有顺序没关系,即:有顺序也行,没有顺序也行!// 而本题要求凑成总和的组合数,元素之间明确要求没有顺序/**以coins[0] = 1, coins[1] = 5, amount = 6为例先遍历物品,就是先把1加入计算,然后再把5加入计算 -> 这样得到的是 组合先遍历背包,背包容量的每一个值,都是经过 1 和 5 的计算,包含了{1, 5} 和 {5, 1}两种情况-> 这样得到的是 排列 不理解的话可以打印dp数组来看看*/for(int i = 0; i < coins.length; ++i) {for(int j = coins[i]; j <= amount; ++j) {dp[j] += dp[j - coins[i]];}for(int ele : dp) {System.out.print(ele + ",");}System.out.println(" ");}return dp[amount];}
}  

组合总和 Ⅳ

题目链接:377. 组合总和 Ⅳ - 力扣(LeetCode)

本题与动态规划:518.零钱兑换II (opens new window)就是一个鲜明的对比,一个是求排列,一个是求组合,遍历顺序完全不同

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]) {dp[i] += dp[i - nums[j]];}}}return dp[target];}
}

相关文章:

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

代码随想录算法训练营第四十四天 | 完全背包 、零钱兑换 II 、组合总和 Ⅳ 完全背包 题目链接&#xff1a;题目页面 (kamacoder.com) 解释一、01背包 一维 &#xff1a;为什么要倒序遍历背包&#xff1f; 首先要明白二维数组的递推过程&#xff0c;然后才能看懂二维变一维的…...

【经验】vscode 鼠标拖曳不能选中整行文字,只能选中纵向矩形范围

1、问题描述 不知道昨天操作vscode设置界面时&#xff0c;误选择了啥&#xff0c;导致鼠标拖曳不能选中整行文字&#xff0c;只能选中纵向矩形范围&#xff0c;现象如下&#xff1a; 2、解决方法 1&#xff09;打开设置界面 点击左下角按键&#xff0c;选择“设置” 2&…...

Redis--事务机制的详解及应用

Redis事务的概念&#xff1a; Redis事务就是将一系列命令包装成一个队列&#xff0c;在执行时候按照添加的顺序依次执行&#xff0c;中间不会被打断或者干扰&#xff0c;在执行事务中&#xff0c;其他客户端提交的命令不可以插入到执行事务的队列中&#xff0c;简单来说Redis事…...

路由器端口映射如何配置?

在网络通信中&#xff0c;路由器是一个重要的设备&#xff0c;它负责将数据包从一个网络传输到另一个网络。路由器的端口映射配置是一种重要的设置&#xff0c;可以使外部网络中的计算机通过访问路由器上的特定端口与内部网络中的计算机进行通信。本文将介绍什么是路由器端口映…...

力扣34. 在排序数组中查找元素的第一个和最后一个位置(二分查找)

Problem: 34. 在排序数组中查找元素的第一个和最后一个位置 文章目录 题目描述思路复杂度Code 题目描述 思路 Problem: 二分查找常用解题模板&#xff08;带一道leetcode题目&#xff09; 直接套用上述中的寻找左、右边界的二分查找模板即可 复杂度 时间复杂度: O ( l o g n )…...

【每日一题】3.2 求逆序对

题目描述 给定一个长度为 n的整数数列&#xff0c;请你计算数列中的逆序对的数量。 逆序对的定义如下&#xff1a;对于数列的第 i个和第 j个元素&#xff0c;如果满足 i<j 且 a[i]>a[j]&#xff0c;则其为一个逆序对&#xff1b;否则不是。 输入格式 第一行包含整数 n…...

NTP时间源服务器(NTP网络时钟)助力智慧医院数字化

NTP时间源服务器&#xff08;NTP网络时钟&#xff09;助力智慧医院数字化 NTP时间源服务器&#xff08;NTP网络时钟&#xff09;助力智慧医院数字化 目前计算机网络中各主机和服务器等网络设备的时间基本处于无序的状态。 随着计算机网络应用的不断涌现&#xff0c;计算机的时…...

Benchmark学习笔记

小记一篇Benchmark的学习笔记 1.什么是benchmark 在维基百科中&#xff0c;是这样子讲的 “As computer architecture advanced, it became more difficult to compare the performance of various computer systems simply by looking at their specifications.Therefore, te…...

Linux中的动静态库

目录 一、静态库 &#xff08;1&#xff09;静态库的优缺点&#xff1a; &#xff08;2&#xff09;Linux下静态库的创建和执行 1.直接编译​编辑 2.指定路径和库名 3.用LIBRARY_PATH环境变量来配置路径 二、动态库 &#xff08;1&#xff09;动态库的优缺点 &#xff…...

C/C++基础语法

C/C基础语法 文章目录 C/C基础语法头文件经典问题链表链表基础操作 秒数转换闰年斐波那契数列打印n阶菱形曼哈顿距离菱形图案的定义大数计算 输入输出格式化输入输出getline()函数解决cin只读入一个单词的问题fgets读入整行输出字符数组&#xff08;两种方式puts和printf&#…...

Home Assistant:基于Python的智能家居开源系统详解

Home Assistant&#xff1a;基于Python的智能家居开源系统详解 在数字化和智能化的时代&#xff0c;智能家居系统成为了现代家庭的新宠。它们能够让我们更加方便地控制家中的各种设备&#xff0c;实现自动化和个性化的居住体验。其中&#xff0c;Home Assistant作为一款基于Pyt…...

使用vscode进行简单的多文件编译

安装好必要的插件后&#xff08;如C/C&#xff0c;code runner等&#xff09;默认生成task.json即可进行单文件运行 涉及到多文件情况可以修改task.json如下&#xff1a; {"version": "2.0.0","tasks": [{"type": "cppbuild&quo…...

Python实现PPT演示文稿中视频的添加、替换及提取

无论是在教室、会议室还是虚拟会议中&#xff0c;PowerPoint 演示文稿都已成为一种无处不在的工具&#xff0c;用于提供具有影响力的可视化内容。PowerPoint 提供了一系列增强演示的功能&#xff0c;在其中加入视频的功能可以大大提升整体体验。视频可以传达复杂的概念、演示产…...

Mysql学习之MVCC解决读写问题

多版本并发控制 什么是MVCC MVCC &#xff08;Multiversion Concurrency Control&#xff09;多版本并发控制。顾名思义&#xff0c;MVCC是通过数据行的多个版本管理来实现数据库的并发控制。这项技术使得在InnoDB的事务隔离级别下执行一致性读操作有了保证。换言之&#xff0…...

Linux下如何生成coredump文件

引言 在linux下执行程序&#xff0c;当出现coredump时&#xff0c;却发现没有生成core文件&#xff0c;或者生成了core文件却不知道在哪里&#xff0c;下面就讲述如何产出core文件&#xff0c;以及指定core文件的产出格式与路径。 打开core文件的大小限制 ulimit -c unlimit…...

eltable 合计行添加tooltip

eltable 合计行添加tooltip 问题描述&#xff1a; eltable 合计行单元格内容过长会换行&#xff0c;需求要求合计行数据超长显示 … &#xff0c;鼠标 hover 时显示提示信息。 解决方案&#xff1a;eltable合计行没有对外的修改接口&#xff0c;想法是 自己实现一个tooltip&a…...

Secure Boot(安全启动)

Secure Boot&#xff08;安全启动&#xff09;的原理基于链式验证&#xff0c;这是一种确保计算机在启动过程中只加载和执行经过认证的软件的机制。这个过程涉及到硬件、固件和操作系统的多个层面。以下是Secure Boot的基本原理&#xff1a; 密钥和证书&#xff1a;Secure Boot…...

大厂面试经验:如何对加密后的数据进行模糊查询操作

加密后的数据对模糊查询不是很友好&#xff0c;本篇就针对加密数据模糊查询这个问题来展开讲一讲实现的思路。 为了数据安全我们在开发过程中经常会对重要的数据进行加密存储&#xff0c;常见的有&#xff1a;密码、手机号、电话号码、详细地址、银行卡号、信用卡验证码等信息…...

修改docker默认存储位置【高版本的docker】

一、修改docker默认存储位置 1、停服务 systemctl stop docker 2、修改/etc/docker/daemon.json添加新的dcoker路径 如"data-root": "/mnt/hdd1/docker" 3、保存后重启服务&#xff1a;systemctl restart docker 二、其他服务的命令 systemctl disab…...

CleanMyMac X2024免费Mac电脑清理和优化工具

CleanMyMac X是一款专业的 Mac 清理和优化工具&#xff0c;它具备一系列强大的功能&#xff0c;可以帮助用户轻松管理和维护他们的 Mac 电脑。以下是一些关于 CleanMyMac X 的主要功能和特点&#xff1a; 智能清理&#xff1a;CleanMyMac X 能够智能识别并清理 Mac 上的无用文件…...

从数据采集到回放验证:ADTF 适配 ROS 的 ADAS 测试实践缎

一、简化查询 1. 先看一下查询的例子 /// /// 账户获取服务 /// /// /// public class AccountGetService(AccountTable table, IShadowBuilder builder) {private readonly SqlSource _source new(builder.DataSource);private readonly IParamQuery _accountQuery build…...

Anything to RealCharacters 2.5D转真人引擎效果展示:动漫角色→写实年龄渐变效果实现

Anything to RealCharacters 2.5D转真人引擎效果展示&#xff1a;动漫角色→写实年龄渐变效果实现 获取更多AI镜像 想探索更多AI镜像和应用场景&#xff1f;访问 CSDN星图镜像广场&#xff0c;提供丰富的预置镜像&#xff0c;覆盖大模型推理、图像生成、视频生成、模型微调等多…...

如何在2025年完美访问Flash内容:CefFlashBrowser完整使用指南

如何在2025年完美访问Flash内容&#xff1a;CefFlashBrowser完整使用指南 【免费下载链接】CefFlashBrowser Flash浏览器 / Flash Browser 项目地址: https://gitcode.com/gh_mirrors/ce/CefFlashBrowser 你是否还在为无法访问那些经典的Flash网站、教育课件和网页游戏而…...

高校无线网络优化实战:从信号覆盖到安全管理的全流程解析

1. 高校无线网络优化的必要性 校园无线网络就像校园里的"水电煤"&#xff0c;已经成为师生日常教学和生活的基础设施。十年前&#xff0c;大家可能只要求"能连上WiFi"就行&#xff0c;但现在的情况完全不同了——教授在阶梯教室用4K视频教学&#xff0c;学…...

ComfyUI工作流分享:一键生成社交媒体配图与头像壁纸

ComfyUI工作流分享&#xff1a;一键生成社交媒体配图与头像壁纸 1. ComfyUI简介与核心优势 ComfyUI是一款基于节点式工作流的AI图像生成工具&#xff0c;它通过可视化连接不同功能模块&#xff0c;让用户可以灵活定制图像生成流程。与传统的WebUI界面相比&#xff0c;ComfyUI…...

操作系统面试必问:FCFS、SJF、HRRN调度算法到底怎么算?一个例子讲透

操作系统面试必问&#xff1a;FCFS、SJF、HRRN调度算法实战解析 在计算机操作系统的面试中&#xff0c;进程调度算法几乎是必考的核心知识点。无论是校招笔试还是技术面谈&#xff0c;面试官都喜欢用"给定一组进程的到达时间和服务时间&#xff0c;请计算不同调度算法下的…...

如何永久保存微信聊天记录?WeChatMsg免费开源工具终极指南

如何永久保存微信聊天记录&#xff1f;WeChatMsg免费开源工具终极指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/W…...

QuickBMS终极指南:三步掌握游戏文件提取与修改的免费神器

QuickBMS终极指南&#xff1a;三步掌握游戏文件提取与修改的免费神器 【免费下载链接】QuickBMS QuickBMS by aluigi - Github Mirror 项目地址: https://gitcode.com/gh_mirrors/qui/QuickBMS QuickBMS是一款革命性的通用文件提取工具&#xff0c;专为游戏资源提取、逆…...

突破限制!OBS虚拟摄像头插件实现4路视频同时分发终极方案

突破限制&#xff01;OBS虚拟摄像头插件实现4路视频同时分发终极方案 【免费下载链接】obs-virtual-cam 项目地址: https://gitcode.com/gh_mirrors/obsv/obs-virtual-cam 你是否曾经遇到过这样的困扰&#xff1f;当你使用OBS进行直播或录制时&#xff0c;想要将画面同…...

告别DHT11!用STM32 HAL库驱动更高精度的AHT10温湿度传感器,附完整工程源码

从DHT11到AHT10&#xff1a;STM32 HAL库高精度温湿度测量实战指南 在智能家居和工业监测领域&#xff0c;温湿度数据的准确性直接影响着系统决策的质量。许多开发者最初接触的DHT11传感器虽然价格低廉&#xff0c;但其5%的湿度误差和2℃的温度偏差常常成为项目瓶颈。当你的智能…...