LeetCode 322. 零钱兑换  

思路1: 回溯算法可以做,只要存储数组的最小长度即可,但可能会超时。

思路2:   相当于是求最大价值的相反面,另外一个物品可以使用多次,因此是个完全背包。因此这是个完全背包的求最小价值类型题目。

注意:

  • 区分达到背包容量的方式 和 区分背包容量下的最大/最小价值,前者(方式)是通过累加递推,后者(价值)是通过max和min函数来递推。
  • 在求最大价值时候,由于每个元素是正数,因此dp数组是初始化为0。max()函数可以有效进行覆盖。但本题是求最小价值,因此dp数组需要初始化为float('inf')即正无穷,这样的话min()函数可以有效进行覆盖。另外,dp[0]是特殊情况,需要根据情况进行手动修改。
class Solution(object):def coinChange(self, coins, amount):""":type coins: List[int]:type amount: int:rtype: int"""## 每种硬币的数量是无限的, 因此是个完全背包。## 可以凑成总金额所需的 最少的硬币个数。关键在于最少的递推公式是什么. 最少的硬币个数不就是求最大价值的相反面吗## 求元素的数目,与价值有关,因此背包和物品的排列顺序可以任意。## 1. dp数组定义。dp[j]表示总金额(背包容量)为j下的最少硬币个数(最少物品数量)dp = [float('inf')] * (amount + 1)      ## 求最大价值的时候,这里是初始化为0## 现在是求最小价值,这里要初始化为最大值## 2. dp初始化# dp[0] = 1       ### 不取也是一种方式。但这里不是求方式,而是求个数dp[0] = 0         ### 因此amount = 0 的时候dp[0]是0个硬币## 3. 递推公式# dp[j] = min(dp[j], (dp[j-coins[i]] + 1)]  ## 每进行一次加法,就证明多了一个硬币## 4. 遍历顺序。 跟组合和排列无关,因此背包和物品的排列顺序可以任意。for i in range(len(coins)):for j in range(coins[i], len(dp)):dp[j] = min(dp[j], (dp[j-coins[i]] + 1) )## 5. 打印 dpif dp[amount] == float('inf'):      ## 硬币的种类凑不到总金额return -1return dp[amount]

LeetCode 279.完全平方数 

思路:

1. 先根据输入的数获取一个物品数组,这个物品长度最短为 math.sqrt(target) 。当math.sqrt(target)平方根为整数时,此时表示target可以基于math.sqrt(target)的完全平方数一次得到。若不是,则需要列出小于math.sqrt(target)的所有可能整数的完全平方数,这个数组就是物品。

2. 搞定物品后其实这道题有差不多有思路了,另外的,递推公式记得+1,因为是要求数量,没加1的话就变成了求构成的完全平方数中的最小元素。

Code:

import math
class Solution(object):def numSquares(self, n):""":type n: int:rtype: int"""### 最少数量即最小价值,物品背包遍历先后顺序不影响### 由于第一个物品可以被用多次,因此是完全背包类型### 物品是一个正整数组 [1,2,3,...,n]### 将上述正整数组平方得到一个正整数组的平方数组[2,4,9,...,n^2]### 最大背包容量为nnums = [0]* (int(math.sqrt(n)))for i in range(len(nums)):nums[i] = (i+1)*(i+1)       ### 起始坐标是从0开始,要右移一位# 1. dp 定义,dp[j],整数为j下,和为j的完全平方数的最少数量dp = [float('inf')] * (n+1)# 2. dp 初始化    dp[0] = 0   ## 0 本身可以不通过别人平方相加得到# 3. 递推公式# dp[j] = min(dp[j], dp[j-nums[i]])# dp[j] = min(dp[j], dp[j-nums[i]]+1)   ## 衡量的是数量因此要加1,而不是上述这个,这个是求其中的一个最小元素。# 4. 遍历顺序for i in range(len(nums)):              # 先遍历物品for j in range(nums[i], len(dp)):   # 再遍历背包dp[j] = min(dp[j], dp[j-nums[i]]+1)# 5. 打印dp# print(dp)return dp[n]

LeetCode 139.单词拆分

类似题目:

LeetCode 131: 分割回文串。 这道题是字符串拆分成回文串,而本题是判断字典中的单词能否组成字符串。

思路:

这道题偏难,即考究字符串的操作,又考究了双指针,结合双指针来设计dp数组。通过一个双指针来遍历指针之间的子字符串是否存在于字典中来进行判断,并将判断结果更新到dp数组中。如下所示:

根据字符串的关系去更新dp数组是关键,下标多会有点乱,要理清dp的下标含义和i,j指向字符串时又表达什么意思。递推公式那里要搞懂。

  • 确定递推公式

如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i )。

所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true。

Code

class Solution(object):def wordBreak(self, s, wordDict):""":type s: str:type wordDict: List[str]:rtype: bool"""### 物品可以被多次使用,因此是完全背包。### 在数字数组中,求和问题可以通过相加来判断。关键:但在字符串中,如何判断字典中的单词拼接起来能否构成该target字符串# 1. dp数组定义。dp[j]表示长度为j的字符串能否由单词表中的单词构成。dp = [False] * (len(s) + 1)     # 2. dp数组初始化。先默认不能由单词表中的单词构成。dp[0] = True            ## 第一个表示空字符串## 虽题目默认了不会有空字符串,但dp[0]需要初始化为True,如果初始化为False, 则后面无法进行递推,所得到的都会是False# 3. 递推公式。关键:递推公式是什么?# if dp[j] == True and [j,i] in word_dict:     ## 如果字符串中的前i个已匹配,且[i,j]这个位置存在子字符串。#       dp[i] = True# 4. 遍历顺序。单词的构成涉及到排列,因此是先遍历背包再遍历物品。for i in range(1, len(dp)):    ## 先遍历背包for j in range(i):         ## 再遍历物品, j始终都是在i的左边,j去追赶i, j和i的这段距离内的子字符串sub_string = s[j:i]    ## j位置开始(包括j)到i(不包括i)的这段子字符串。 i-j这段区间有i-j个字符if dp[j] == True and sub_string in wordDict:dp[i] = True       ## j + i - j = i,前j个字符可行,现在从第j开始的i-j个字符可行,因此前i个字符可行# break             ## 不break也可以,break是对一些多余的循环进行剪枝# 5. 打印dp数组return dp[len(s)]

多重背包基础

  • 01背包是一个物品只能用一次
  • 完全背包是一个物品能用无数次
  • 多重背包是一个物品能用x次

涉及多重背包的题目较少,如遇到的话,将其转化为01背包就行。如下所示:

56. 携带矿石资源

思路1:

将多重背包转换为01背包进行解决。

需要注意如何将多重转换为01问题,另外01问题在遍历背包时需要注意顺序。

Code

bagroom, category = input().split()
bagroom, category = int(bagroom), int(category)weight = []
for x in input().split():weight.append(int(x))price = []
for x in input().split():price.append(int(x))nums = []
for x in input().split():nums.append(int(x))for i in range(len(nums)):      ### 将多重背包转换为01背包处理, 但如果nums数目过大的话,会导致01背包中物品数组的长度很大,进而导致超时。count = nums[i]while count != 1:weight.append(weight[i])price.append(price[i])count -= 1# 1. dp定义,dp[j]表示背包容量为j下背包的最大价值
dp = [0] * (bagroom + 1)# 2. dp初始化,初始化为0
# 3. 递推公式。dp[j] = max(dp[j], dp[j-weight[i]+price[i]])
# 4. 遍历顺序
for i in range(len(weight)):                ## 先物品再背包容量for j in range(len(dp)-1, weight[i]-1, -1): ## 01背包这里要逆序遍历,确保每个物品只用一次dp[j] = max(dp[j], dp[j-weight[i]]+price[i])
# 5. 打印dp数组
# print(dp)
print(dp[bagroom])

思路2:

对物品的数目也进行一个循环操作,来判断物品的数目添加多少时可以达到最大价值。其实就是多加了个循环来判断当前物品要装多少个,来得到最大价值。

Code:

bagroom, category = input().split()
bagroom, category = int(bagroom), int(category)weight = []
for x in input().split():weight.append(int(x))price = []
for x in input().split():price.append(int(x))nums = []
for x in input().split():nums.append(int(x))# 1. dp定义,dp[j]表示背包容量为j下背包的最大价值
dp = [0] * (bagroom + 1)# 2. dp初始化,初始化为0
# 3. 递推公式。dp[j] = max(dp[j], dp[j-k*weight[i]+k*price[i]])
# 4. 遍历顺序
for i in range(len(weight)):                ## 先物品再背包容量for j in range(len(dp)-1, weight[i]-1, -1): ## 这里要逆序遍历,确保每个物品只用一次for k in range(1, nums[i]+1):   ## nums[i]+1 确保最后一个数可以被遍历到。range是左闭右开。if j < k*weight[i]:     ## 背包容量不够,那再大的k可以不用遍历了breakdp[j] = max(dp[j], dp[j-k*weight[i]]+ k*price[i])# 5. 打印dp数组
# print(dp)
print(dp[bagroom])

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

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

相关文章

JAVA面试宝典 -《Elasticsearch 深度调优实战》

文章目录一、引言&#xff1a;搜索引擎为啥越来越慢&#xff1f;1.1 典型业务场景性能瓶颈表现​​&#xff1a;二、倒排索引压缩&#xff1a;让存储与检索更高效&#x1f9e0; 2.1倒排索引结构简述&#x1f527; 2.2 压缩算法三剑客✅ 调优建议三、分片策略&#xff1a;写入性…

克鲁斯焊接机器人保护气省气方案

在现代焊接工艺中&#xff0c;克鲁斯焊接机器人扮演着至关重要的角色。随着制造业对成本控制和可持续发展的日益重视&#xff0c;焊接过程中的保护气省气问题成为了焦点。WGFACS节气装置为克鲁斯焊接机器人的保护气省气提供了一种创新且有效的解决方案。克鲁斯焊接机器人以其高…

JavaEE——多线程中的哈希表

目录前言1.HashTable2.ConcurrentHashMap总结前言 在使用多线程前&#xff0c;我们用HashMap类来创建哈希表&#xff0c;但这个类线程不安全&#xff0c;在这篇文章&#xff0c;我们将介绍多线程环境的哈希表&#xff0c;将会讲述HashTable, HashMap, ConcurrentHashMap这三个…

MyBatis Plus SQL性能分析:从日志到优化的全流程实战指南

引言 在Java开发的江湖里&#xff0c;MyBatis Plus&#xff08;MP&#xff09;早已是“效率利器”——它用极简的API封装了CRUD操作&#xff0c;让开发者从重复的SQL编写中解放出来。但随着项目数据量从“万级”跃升至“十万级”“百万级”&#xff0c;一个尴尬的现实逐渐浮现&…

备忘录设计模式

备忘录模式&#xff08;Memento Pattern&#xff09;是一种行为设计模式&#xff0c;用于捕获对象的内部状态并在需要时恢复该状态&#xff0c;同时不破坏对象的封装性。它适用于需要实现撤销/重做、历史记录或状态快照的场景。核心组件Originator&#xff08;原发器&#xff0…

【世纪龙科技】智能网联汽车环境感知系统教学难题的创新实践​

在职业院校智能网联汽车专业教学中&#xff0c;环境感知系统的教学长期面临三大核心挑战&#xff1a;设备成本高昂导致实训资源不足、抽象原理难以直观呈现、传统教学模式难以满足产业需求。如何让学生在有限的教学条件下&#xff0c;深入理解激光雷达、毫米波雷达等核心部件的…

ES vs Milvus vs PG vector :LLM时代的向量数据库选型指南

互联网时代&#xff0c;关系型数据库为王。相应的&#xff0c;我们的检索方式也是精确匹配查询为主——查找特定的用户ID、商品编号或订单状态。但AI时代&#xff0c;语义检索成为常态&#xff0c;向量数据库成为搜索推荐系统&#xff0c;大模型RAG落地&#xff0c;自动驾驶数据…

磁盘阵列技术的功能与分类

磁盘阵列技术 磁盘阵列是由多台磁盘存储器组成的一个快速、大容量、高可靠的外存子系统。现在常见的磁盘阵列称为廉价冗余磁盘阵列&#xff08;Redundant Array of Independent Disk,RAID)。目前&#xff0c;常见的 RAID 如下所示。 廉价冗余磁盘阵列 RAID级别 RAID-0是一种不具…

SpringMVC核心注解:@RequestMapping详解

概述RequestMapping是SpringMVC中最核心的注解之一&#xff0c;用于将HTTP请求映射到MVC和REST控制器的处理方法上。基本功能RequestMapping主要用于&#xff1a;映射URL到控制器类或方法定义请求方法类型&#xff08;GET、POST等&#xff09;定义请求参数、请求头等条件使用位…

【杂谈】硬件工程师怎么用好AI工具做失效分析

最近被派到国外出差了&#xff0c;工作任务比较重&#xff0c;所以更新的频率比较低。但在出差工作的过程中&#xff0c;我发现在失效分析时&#xff0c;有相当多的时间做的是比较重复的工作。比如失效分析肯定要一些证据如图片、视频。当我们做多台设备的失效分析时&#xff0…

MyBatis详解以及在IDEA中的开发

MyBatis概述 MyBatis是一个优秀的持久层框架&#xff0c;它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的过程。 核心特点 优势&#xff1a; SQL语句与Java代码分离&#xff0c;便于维护支持动态SQL&#xff0c;灵活性…

LangGraph教程6:LangGraph工作流人机交互

文章目录 Human-in-the-loop(人机交互) interrupt Warning Human-in-the-loop(人机交互) 人机交互(或称“在循环中”)工作流将人类输入整合到自动化过程中,在关键阶段允许决策、验证或修正。这在基于 LLM 的应用中尤其有用,因为基础模型可能会产生偶尔的不准确性。在合规、…

Linux部署Milvus数据库及Attu UI工具完全指南

一、准备工作1.1 环境要求操作系统&#xff1a;Ubuntu 20.04/Debian 11/CentOS 7硬件配置&#xff1a;至少8GB内存&#xff0c;4核CPU&#xff0c;50GB磁盘空间网络要求&#xff1a;可访问互联网&#xff08;用于拉取Docker镜像&#xff09;1.2 安装Docker和Docker Compose1.2.…

开疆智能Profinet转ModbusTCP网关连接康耐视InSight相机案例

相机配置&#xff1a;硬件连接部分可以查询我的博客&#xff1a;点击 这里不做说明。在电子表格视图下&#xff0c;点击菜单 “传感器–网络设置”&#xff1a;选择工业协议&#xff0c;如图。保存作业&#xff0c;并按照提示重启相机。3. 相机的控制/状态字&#xff1a;上图中…

BERT技术架构

### **一、整体定位&#xff1a;纯编码器架构**#### **核心设计思想**> **预训练微调**&#xff1a;> 1. **预训练**&#xff1a;在海量无标签文本上学习通用语言规律> 2. **微调**&#xff1a;用少量标注数据适配具体任务&#xff08;如分类/问答&#xff09;> **…

Python+ArcGIS+AI蒸散发与GPP估算|Penman-Monteith模型|FLUXNET数据处理|多源产品融合|专业科研绘图与可视化等

结合Python编程与ArcGIS工具&#xff0c;通过AI辅助方法实现蒸散发与植被总初级生产力估算。学习国际流行的Penman-Monteith模型&#xff0c;掌握数据获取、处理、分析和可视化全流程&#xff0c;培养生态水文与双碳领域的实践应用能力。通过DeepSeek、豆包等AI工具辅助代码编写…

elasticsearch+logstash+kibana+filebeat实现niginx日志收集(未过滤日志内容)

单点部署 环境准备 基于Rocky9虚拟机&#xff0c;内存大小为4G yum -y install lrzsz useradd elkf passwd elkf#密码随意su - elk rz 导入包&#xff0c;笔者导使用版本为7.17.8下载地址&#xff1a;https://www.elastic.co/downloads/past-releases/ tar -xf elasticsearch-7…

hadoop 集群问题处理

1.1.JournalNode 的作用在 HDFS HA 配置中&#xff0c;为了实现两个 NameNode 之间的状态同步和故障自动切换&#xff0c;Hadoop 使用了一组 JournalNode 来管理共享的编辑日志。具体来说&#xff0c;JournalNode 的主要职责包括&#xff1a;共享编辑日志&#xff1a;JournalNo…

LeetCode--46.全排列

解题思路&#xff1a;1.获取信息&#xff1a;给定一个不含重复数字的数组&#xff0c;返回所有可能的全排列&#xff0c;可以按任意顺序返回提示信息&#xff1a;1 < nums.length < 6-10 < nums[i] < 102.分析题目&#xff1a;要获取到所有可能的全排列我们每次会从…

云徙科技----一面(全栈开发)

一、公司是做什么业务的&#xff1f;二、介绍一下自己会用的&#xff0c;熟悉的技术栈&#xff1f;三、“在 Spring 应用中&#xff0c;当你发起一个 RESTful API 请求时&#xff08;例如 GET /api/users/1&#xff09;&#xff0c;计算机系统是如何知道这个请求的&#xff1f;…