代码随想录算法训练营第三十九天 | 198.打家劫舍 , 213.打家劫舍II , 337.打家劫舍III

news/2024/9/14 2:00:25/ 标签: 算法, 数据结构, python, leetcode, 动态规划, 树形贪心

目录

198.打家劫舍

思路

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

2.确定递推公式

3.dp数组如何初始化

4.确定遍历顺序

5.举例推导dp数组

方法一: 动态规划-一维

方法二:动态规划-二维

方法三:动态规划-两个变量

213.打家劫舍II

思路

方法一:动态规划-

方法二:动态规划-二维

方法三:动态规划-不封装函数

 337.打家劫舍III 

算法公开课-toc" style="margin-left:40px;">

思路

暴力递归

记忆化递推

动态规划-toc" style="margin-left:80px;">动态规划

1.确定递归函数的参数和返回值

2.确定终止条件

3.确定遍历顺序

4.确定单层递归的逻辑

5.举例推导dp数组

方法一:暴力递归

方法二:记忆化递归

方法三:动态规划


198.打家劫舍

  • 题目链接:力扣题目链接
  • 文章讲解:代码随想录 

  • 视频讲解:动态规划,偷不偷这个房间呢?| LeetCode:198.打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

  • 示例 1:
  • 输入:[1,2,3,1]
  • 输出:4

解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。   偷窃到的最高金额 = 1 + 3 = 4 。

  • 示例 2:
  • 输入:[2,7,9,3,1]
  • 输出:12 解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。   偷窃到的最高金额 = 2 + 9 + 1 = 12 。

提示:

  • 0 <= nums.length <= 100
  • 0 <= nums[i] <= 400

思路

仔细一想,当前房屋偷与不偷取决于 前一个房屋和前两个房屋是否被偷了。

所以这里就更感觉到,当前状态和前面状态会有一种依赖关系,那么这种依赖关系都是动规的递推公式。

当然以上是大概思路,打家劫舍是dp解决的经典问题,接下来我们来动规五部曲分析如下:

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

dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]

2.确定递推公式

决定dp[i]的因素就是第i房间偷还是不偷。

如果偷第i房间,那么dp[i] = dp[i - 2] + nums[i] ,即:第i-1房一定是不考虑的,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。

如果不偷第i房间,那么dp[i] = dp[i - 1],即考 虑i-1房,(注意这里是考虑,并不是一定要偷i-1房,这是很多同学容易混淆的点

然后dp[i]取最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);

3.dp数组如何初始化

从递推公式dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);可以看出,递推公式的基础就是dp[0] 和 dp[1]

从dp[i]的定义上来讲,dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);

4.确定遍历顺序

dp[i] 是根据dp[i - 2] 和 dp[i - 1] 推导出来的,那么一定是从前到后遍历!

5.举例推导dp数组

以示例二,输入[2,7,9,3,1]为例。

198.打家劫舍

红框dp[nums.size() - 1]为结果。

方法一: 动态规划-一维

python">class Solution:def rob(self, nums: List[int]) -> int:if len(nums) == 0:  # 如果没有房屋,返回0return 0if len(nums) == 1:  # 如果只有一个房屋,返回其金额return nums[0]# 创建一个动态规划数组,用于存储最大金额dp = [0] * len(nums)dp[0] = nums[0]  # 将dp的第一个元素设置为第一个房屋的金额dp[1] = max(nums[0], nums[1])  # 将dp的第二个元素设置为第一二个房屋中的金额较大者# 遍历剩余的房屋for i in range(2, len(nums)):# 对于每个房屋,选择抢劫当前房屋和抢劫前一个房屋的最大金额dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])return dp[-1]  # 返回最后一个房屋中可抢劫的最大金额

方法二:动态规划-二维

python">class Solution:def rob(self, nums: List[int]) -> int:if not nums:  # 如果没有房屋,返回0return 0n = len(nums)dp = [[0, 0] for _ in range(n)]  # 创建二维动态规划数组,dp[i][0]表示不抢劫第i个房屋的最大金额,dp[i][1]表示抢劫第i个房屋的最大金额dp[0][1] = nums[0]  # 抢劫第一个房屋的最大金额为第一个房屋的金额for i in range(1, n):dp[i][0] = max(dp[i-1][0], dp[i-1][1])  # 不抢劫第i个房屋,最大金额为前一个房屋抢劫和不抢劫的最大值dp[i][1] = dp[i-1][0] + nums[i]  # 抢劫第i个房屋,最大金额为前一个房屋不抢劫的最大金额加上当前房屋的金额return max(dp[n-1][0], dp[n-1][1])  # 返回最后一个房屋中可抢劫的最大金额

方法三:动态规划-两个变量

python">class Solution:def rob(self, nums: List[int]) -> int:if not nums:  # 如果没有房屋,返回0return 0prev_max = 0  # 上一个房屋的最大金额curr_max = 0  # 当前房屋的最大金额for num in nums:temp = curr_max  # 临时变量保存当前房屋的最大金额curr_max = max(prev_max + num, curr_max)  # 更新当前房屋的最大金额prev_max = temp  # 更新上一个房屋的最大金额return curr_max  # 返回最后一个房屋中可抢劫的最大金额

213.打家劫舍II

  • 题目链接:力扣题目链接
  • 文章讲解:代码随想录 

  • 视频讲解:动态规划,房间连成环了那还偷不偷呢?| LeetCode:213.打家劫舍II

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。

给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,能够偷窃到的最高金额。

示例 1:

  • 输入:nums = [2,3,2]

  • 输出:3

  • 解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。

  • 示例 2:

  • 输入:nums = [1,2,3,1]

  • 输出:4

  • 解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。

  • 示例 3:

  • 输入:nums = [0]

  • 输出:0

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 1000

思路

这道题目和198.打家劫舍 是差不多的,唯一区别就是成环了。

对于一个数组,成环的话主要有如下三种情况:

  • 情况一:考虑不包含首尾元素

213.打家劫舍II

  • 情况二:考虑包含首元素,不包含尾元素

213.打家劫舍II1

  • 情况三:考虑包含尾元素,不包含首元素

213.打家劫舍II2

注意我这里用的是"考虑",例如情况三,虽然是考虑包含尾元素,但不一定要选尾部元素! 对于情况三,取nums[1] 和 nums[3]就是最大的。

而情况二 和 情况三 都包含了情况一了,所以只考虑情况二和情况三就可以了

分析到这里,本题其实比较简单了。 剩下的和198.打家劫舍就是一样的了。

方法一:动态规划-

python">class Solution:def rob(self, nums: List[int]) -> int:if len(nums) == 0:return 0if len(nums) == 1:return nums[0]result1 = self.robRange(nums, 0, len(nums) - 2)  # 情况二result2 = self.robRange(nums, 1, len(nums) - 1)  # 情况三return max(result1, result2)# 198.打家劫舍的逻辑def robRange(self, nums: List[int], start: int, end: int) -> int:if end == start:return nums[start]prev_max = nums[start]curr_max = max(nums[start], nums[start + 1])for i in range(start + 2, end + 1):temp = curr_maxcurr_max = max(prev_max + nums[i], curr_max)prev_max = tempreturn curr_max

方法二:动态规划-二维

python">class Solution:def rob(self, nums: List[int]) -> int:if len(nums) < 3:return max(nums)# 情况二:不抢劫第一个房屋result1 = self.robRange(nums[:-1])# 情况三:不抢劫最后一个房屋result2 = self.robRange(nums[1:])return max(result1, result2)def robRange(self, nums):dp = [[0, 0] for _ in range(len(nums))]dp[0][1] = nums[0]for i in range(1, len(nums)):dp[i][0] = max(dp[i - 1])dp[i][1] = dp[i - 1][0] + nums[i]return max(dp[-1])

方法三:动态规划-不封装函数

python">class Solution:def rob(self, nums: List[int]) -> int:if not nums:  # 如果没有房屋,返回0return 0if len(nums) == 1:  # 如果只有一个房屋,返回该房屋的金额return nums[0]# 情况二:不抢劫第一个房屋prev_max = 0  # 上一个房屋的最大金额curr_max = 0  # 当前房屋的最大金额for num in nums[1:]:temp = curr_max  # 临时变量保存当前房屋的最大金额curr_max = max(prev_max + num, curr_max)  # 更新当前房屋的最大金额prev_max = temp  # 更新上一个房屋的最大金额result1 = curr_max# 情况三:不抢劫最后一个房屋prev_max = 0  # 上一个房屋的最大金额curr_max = 0  # 当前房屋的最大金额for num in nums[:-1]:temp = curr_max  # 临时变量保存当前房屋的最大金额curr_max = max(prev_max + num, curr_max)  # 更新当前房屋的最大金额prev_max = temp  # 更新上一个房屋的最大金额result2 = curr_maxreturn max(result1, result2)

 337.打家劫舍III 

  • 题目链接:力扣题目链接
  • 文章讲解:代码随想录 

  • 视频讲解:动态规划,房间连成树了,偷不偷呢?| LeetCode:337.打家劫舍3

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

337.打家劫舍III

算法公开课">

思路

这道题目和 198.打家劫舍 ,213.打家劫舍II 也是如出一辙,只不过这个换成了树。

如果对树的遍历不够熟悉的话,那本题就有难度了。

对于树的话,首先就要想到遍历方式,前中后序(深度优先搜索)还是层序遍历(广度优先搜索)。

本题一定是要后序遍历,因为通过递归函数的返回值来做下一步计算

与198.打家劫舍,213.打家劫舍II一样,关键是要讨论当前节点抢还是不抢。

如果抢了当前节点,两个孩子就不能动,如果没抢当前节点,就可以考虑抢左右孩子(注意这里说的是“考虑”

暴力递归

  • 时间复杂度:O(n^2),这个时间复杂度不太标准,也不容易准确化,例如越往下的节点重复计算次数就越多
  • 空间复杂度:O(log n),算上递推系统栈的空间

当然以上代码超时了,这个递归的过程中其实是有重复计算了。

我们计算了root的四个孙子(左右孩子的孩子)为头结点的子树的情况,又计算了root的左右孩子为头结点的子树的情况,计算左右孩子的时候其实又把孙子计算了一遍。

记忆化递推

所以可以使用一个map把计算过的结果保存一下,这样如果计算过孙子了,那么计算孩子的时候可以复用孙子节点的结果。

  • 时间复杂度:O(n)
  • 空间复杂度:O(log n),算上递推系统栈的空间

动态规划">动态规划

在上面两种方法,其实对一个节点 偷与不偷得到的最大金钱都没有做记录,而是需要实时计算。

动态规划其实就是使用状态转移容器来记录状态的变化,这里可以使用一个长度为2的数组,记录当前节点偷与不偷所得到的的最大金钱。

这道题目算是树形dp的入门题目,因为是在树上进行状态转移,我们在讲解二叉树的时候说过递归三部曲,那么下面我以递归三部曲为框架,其中融合动规五部曲的内容来进行讲解

1.确定递归函数的参数和返回值

这里我们要求一个节点 偷与不偷的两个状态所得到的金钱,那么返回值就是一个长度为2的数组。

其实这里的返回数组就是dp数组。

所以dp数组(dp table)以及下标的含义:下标为0记录不偷该节点所得到的的最大金钱,下标为1记录偷该节点所得到的的最大金钱。

所以本题dp数组就是一个长度为2的数组!

那么有同学可能疑惑,长度为2的数组怎么标记树中每个节点的状态呢?

别忘了在递归的过程中,系统栈会保存每一层递归的参数

如果还不理解的话,就接着往下看,看到代码就理解了哈。

2.确定终止条件

在遍历的过程中,如果遇到空节点的话,很明显,无论偷还是不偷都是0,所以就返回

这也相当于dp数组的初始化

3.确定遍历顺序

首先明确的是使用后序遍历。 因为要通过递归函数的返回值来做下一步计算。

通过递归左节点,得到左节点偷与不偷的金钱。

通过递归右节点,得到右节点偷与不偷的金钱。

4.确定单层递归的逻辑

如果是偷当前节点,那么左右孩子就不能偷,val1 = cur->val + left[0] + right[0]; (如果对下标含义不理解就再回顾一下dp数组的含义

如果不偷当前节点,那么左右孩子就可以偷,至于到底偷不偷一定是选一个最大的,所以:val2 = max(left[0], left[1]) + max(right[0], right[1]);

最后当前节点的状态就是{val2, val1}; 即:{不偷当前节点得到的最大金钱,偷当前节点得到的最大金钱}

5.举例推导dp数组

以示例1为例,dp数组状态如下:(注意用后序遍历的方式推导

最后头结点就是 取下标0 和 下标1的最大值就是偷得的最大金钱

方法一:暴力递归

python">
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def rob(self, root: TreeNode) -> int:if root is None:return 0if root.left is None and root.right  is None:return root.val# 偷父节点val1 = root.valif root.left:val1 += self.rob(root.left.left) + self.rob(root.left.right)if root.right:val1 += self.rob(root.right.left) + self.rob(root.right.right)# 不偷父节点val2 = self.rob(root.left) + self.rob(root.right)return max(val1, val2)

方法二:记忆化递归

python"># Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:memory = {}def rob(self, root: TreeNode) -> int:if root is None:return 0if root.left is None and root.right  is None:return root.valif self.memory.get(root) is not None:return self.memory[root]# 偷父节点val1 = root.valif root.left:val1 += self.rob(root.left.left) + self.rob(root.left.right)if root.right:val1 += self.rob(root.right.left) + self.rob(root.right.right)# 不偷父节点val2 = self.rob(root.left) + self.rob(root.right)self.memory[root] = max(val1, val2)return max(val1, val2)

方法三:动态规划

python"># Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:def rob(self, root: Optional[TreeNode]) -> int:# dp数组(dp table)以及下标的含义:# 1. 下标为 0 记录 **不偷该节点** 所得到的的最大金钱# 2. 下标为 1 记录 **偷该节点** 所得到的的最大金钱dp = self.traversal(root)return max(dp)# 要用后序遍历, 因为要通过递归函数的返回值来做下一步计算def traversal(self, node):# 递归终止条件,就是遇到了空节点,那肯定是不偷的if not node:return (0, 0)left = self.traversal(node.left)right = self.traversal(node.right)# 不偷当前节点, 偷子节点val_0 = max(left[0], left[1]) + max(right[0], right[1])# 偷当前节点, 不偷子节点val_1 = node.val + left[0] + right[0]return (val_0, val_1)


http://www.ppmy.cn/news/1516569.html

相关文章

JVM上篇:内存与垃圾回收篇-07-方法区

笔记来源&#xff1a;尚硅谷 JVM 全套教程&#xff0c;百万播放&#xff0c;全网巅峰&#xff08;宋红康详解 java 虚拟机&#xff09; 文章目录 7. 方法区7.1. 栈、堆、方法区的交互关系7.2. 方法区的理解7.2.1. 方法区在哪里&#xff1f;7.2.2. 方法区的基本理解7.2.3. HotSp…

基于 Transformer 的深度学习混合架构用于相位展开

原文&#xff1a;Transformer based deep learning hybrid architecture for phase unwrapping &#x1f4a1; 摘要&#xff1a;提出了一种用于相位展开的深度学习混合架构。混合架构基于卷积神经网络 (CNN) 与视觉变换器的集成。将混合架构/网络在相位展开中的性能与基于 CNN …

使用AWS的EC2服务如何降低成本

在现代企业中&#xff0c;云计算已经成为推动业务创新和发展的重要工具。亚马逊云服务&#xff08;AWS&#xff09;的弹性计算云&#xff08;EC2&#xff09;提供了灵活的计算能力&#xff0c;企业可以根据需求快速部署和管理应用。然而&#xff0c;如何在使用EC2服务的过程中有…

【MySql】深入解析MySQL底层基础知识:存储引擎、数据结构与磁盘交互

一、引言 MySQL作为一款广泛使用的开源关系型数据库管理系统&#xff0c;其底层基础知识对于数据库管理员和开发者来说至关重要。本文将详细介绍MySQL的存储引擎、数据结构以及数据在磁盘上的存储和读取机制&#xff0c;帮助读者更好地理解MySQL的内部工作原理。 二、MySQL存…

后端微服务与分布式系统

编写一篇关于后端微服务和分布式系统的文档&#xff0c;需要详细讨论微服务架构的核心概念、优缺点、关键技术&#xff0c;以及在分布式系统中的应用。以下是文档的大纲和内容概述&#xff1a; 后端微服务与分布式系统 1. 简介 微服务架构是一种将大型应用程序分解为一系列小…

Java学习笔记(04)String与可变字符序列:StringBuffer、StringBuilder的区别

前言&#xff1a; 因为String对象是不可变对象&#xff0c;虽然可以共享常量对象&#xff0c;但是对于频繁字符串的修改和拼接操作&#xff0c;效率极低&#xff0c;空间消耗也比较高。因此&#xff0c;JDK又在java.lang包提供了可变字符序列StringBuffer和StringBuilder类型。…

opencv-4.8.0 Yes everything works with CUDA 12.3 and cuDNN 8.9.7.

opencv-4.8.0 CUDA 12.3 DNN 8.9.7 完美编译运行 脚本&#xff1a; sudo apt-get install libeigen3-dev sudo apt-get install protobuf-compiler sudo apt-get install libeigen3-dev sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen cd ${current_path}/deps…

8月26日,恭喜CUUG 肖同学获得19c OCM证书!

8月26日&#xff0c;恭喜CUUG 肖同学获得Oracle 19c OCM证书。 19c OCM 考试大纲&#xff1a; Skillset 1&#xff1a;常用数据库与网络管理 Skillset 2.1&#xff1a;管理数据库的可用性 Skillset 2.2&#xff1a;数据仓库管理 Skillset 2.3&#xff1a;数据管理 Skillse…

【ORACLE】如何使用 EXPLAIN PLAN来分析和优化包含 GROUP BY 的查询?

在Oracle数据库中&#xff0c;使用EXPLAIN PLAN来分析和优化包含GROUP BY的查询是一个重要的性能调优步骤。以下是如何使用EXPLAIN PLAN来分析这类查询&#xff0c;并提供一些优化建议的步骤&#xff1a; 步骤 1: 生成执行计划 首先&#xff0c;你需要为包含GROUP BY的查询生…

MySQL中的锁详解

1.概念 锁是计算机协调多个进程或者线程并发访问某一资源的机制。那么如何保证数据并发访问的一致性、有效性是数据库必须解决的一个问题&#xff0c;锁的冲突也是影响数据库并发访问性能的一个重要因素&#xff0c;所以数据库中锁的应用极为重要&#xff0c;其复杂度也更高。 …

Kafka的生产者和消费者机制

目录 1.基础的客户端 1.1消息发送者的主流程 1.2消息消费者主流程 2.客户端工作机制 2.1消费者分组消费机制 2.2生产者拦截器机制 2.3消息序列化机制 2.4消息分区路由机制 2.5生产者消息缓存机制 2.6发送应答机制 2.7生产者消息幂等性 (1)生产者消息幂等性介绍 (2…

sql报错之 : The user specified as a definer (‘xxx‘@‘%‘) does not exiet

报错详情 : 其中这个xxx是在定义触发器的时候 的 定义者 &#xff0c; 触发器详情代码 : ## 创建新增评论数据触发器&#xff0c;一旦新增评论则对应视频的评论量加一 CREATE DEFINERxxx% TRIGGER increment_comment_count AFTER INSERT ON comment FOR EACH ROW BEGINUPDAT…

mac在终端中使用vscode打开文件或者文件夹

在Mac上使用Visual Studio Code&#xff08;VSCode&#xff09;打开指定文件夹&#xff0c;你可以通过以下步骤操作&#xff1a; 1.创建软连接 1.找到VSCode的安装位置。在Finder中&#xff0c;导航到/Applications/Visual Studio Code.app 2.进入VSCode的内容文件夹&#x…

小琳AI课堂:使用ChatGPT API搭建系统(二)

&#x1f389; Python与ChatGPT API的奇妙之旅 &#x1f389; 大家好&#xff0c;欢迎回到小琳AI课堂&#xff01;今天我们要探索的是如何在“使用ChatGPT API搭建系统”课程中&#xff0c;用Python代码与ChatGPT API进行有趣的互动。准备好了吗&#xff1f;让我们开始吧&#…

Leetcode每日刷题之1658.将x减到0的最小操作数(C++)

1.题目解析 本题的要求是给出一个正整数数组与一个x&#xff0c;要求只从数组两端取数据后x减去取出的数据&#xff0c;求出将x减为0的最小操作数&#xff0c;即找出数组两端的数字保证其和为x并且要求取出的数字个数最少&#xff0c;如果没有符合要求的数字则返回-1 题目来源&…

使用redis模拟cookie-session,例子:实现验证码功能

目录 在前后端分离架构中不建议使用cookie-session机制实现端状态识别 所以我们可以使用redis来模拟session-cookie机制 下面我们通过实现验证码的功能来举例 第一步&#xff1a;了解前端要我们返回的数据变量名字&#xff0c;变量类型 1.封装code,data成一个result类&…

Android 架构模式之 MVVM

Android 架构 Android 架构模式之 MVCAndroid 架构模式之 MVPAndroid 架构模式之 MVVM 目录 Android 架构架构设计的目的对 MVVM 的理解代码ModelViewViewModel Android 中 MVVM 的问题试吃个小李子BeanModelViewViewModel效果展示 大家好&#xff01; 作为 Android 程序猿&a…

卡片写作只是基础

卡片写作法&#xff0c;降低了写作门槛&#xff0c;让很多人开始喜欢写作&#xff0c;积累了不少。 接下来问题来了&#xff0c;卡片写作的内容&#xff0c;将来怎么输出啊&#xff0c;卡片和文章什么关系&#xff1f;如何写成文章&#xff1f; 这个问题&#xff0c;我最初以…

深度学习----------------------残差网络ResNet

目录 ResNet加更多的层总是改进精度吗&#xff1f;残差块ResNet块细节不同的残差块ResNet块ResNet架构总结 ResNet代码实现残差块输入和输出形状一致增加输出通道数的同时&#xff0c;减半输出的高和宽ResNet模型观察ResNet中不同模块的输入形状是如何变化的训练模型 问题ResNe…

有效提高媒体曝光率,智能推荐为什么是“最大的计算系统之一”?

导语&#xff1a;我认为很少有人意识到&#xff0c;推荐系统是世界上构想过的最大的计算系统之一。——Jensen Huang &#xfeff; 在信息过载的时代背景下&#xff0c;智能推荐系统已广泛应用于电子商务、社交媒体、新闻资讯、视频音乐、旅游出行等领域&#xff0c;为用户提…