动态规划02-斐波那契类型二

这篇具有很好参考价值的文章主要介绍了动态规划02-斐波那契类型二。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 使用最小花费爬楼梯

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

真题点击此处:746.使用最小花费爬楼梯

解题方法:动态规划
思路:对于此题来说,假设cost的长度为n,那么我们可以令前n个楼梯的下标为0–n-1,因此这个问题本质上就是算出当下标为n时的费用即可。我们假设爬到当前下标 i 的耗费为dp[i](不包括当前 i 位置的消费),由题意可知,每次可以爬一个或两个台阶,那么我们就可以得出以下的动态转移方程:dp[i]=min(dp[i−1]+cost[i−1],dp[i−2]+cost[i−2])。
依次计算 dp 中的每一项的值,最终得到的 dp[n]即为达到楼层顶部的最小花费。

以下为代码实现:

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        dp = [0] * (n+1)
        for i in range(2,n+1):
            dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
        return dp[n]

时间复杂度:O(n),使用了一次循环。
空间复杂度:O(n),使用了长度为n+1的数组。

上述代码的时间复杂度和空间复杂度都是 O(n)。注意到当 i≥2 时,dp[i]只和 dp[i−1] 与 dp[i−2]有关,因此可以使用滚动数组的思想,将空间复杂度优化到 O(1)。
以下为代码实现:

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n=len(cost)
        prev = curr = 0
        for i in range(2,n+1):
            nxt = min(curr + cost[i-1], prev + cost[i-2])
            prev, curr = curr, nxt
        return nxt

时间复杂度:O(n),同样的也是一次循环。
空间复杂度:O(1),只使用了常量级的额外空间。

我们也可以直接在cost[i]上修改值,但是这样的话就要加上当前位置的cost[i],并且在循环结束后需要再判断一次最后两个值的大小。
以下为代码实现:

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n=len(cost)
        for i in range(2,n):
            cost[i] = cost[i] + min(cost[i-1], cost[i-2])
        
        return min(cost[-1], cost[-2])

时间复杂度:O(n),一次循环。
空间复杂度:O(1),是在原本的数组上更改,并未创建额外的数组。

2. 打家劫舍

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

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

真题点击此处:198.打家劫舍

解题方法:动态规划
思路:对于一间房屋,偷窃该房屋可以获得最高总金额。对于两间相邻的房屋,只能选择其中金额较高的一间进行偷窃,以获取最高总金额。对于超过两间房屋的情况,每间房屋都有两个选项:偷窃该房屋或者不偷窃该房屋。如果选择偷窃该房屋,需要加上前两间房屋中的最高总金额;如果选择不偷窃该房屋,就直接等于前一间房屋的最高总金额。最后选取偷窃和不偷窃中的最大值作为当前房屋的最高总金额,并重复这个过程直到最后一间房屋。

我们用 dp[i] 表示前 i 间房屋能偷窃到的最高总金额,那么就有如下的状态转移方程:

							dp[i]=max⁡(dp[i−2]+nums[i],dp[i−1])

以下为代码实现:

class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 1:
            return nums[0]

        dp = [0] * n
        dp[0] = nums[0]
        dp[1] = max(nums[0], nums[1])

        for i in range(2,n):
            dp[i] = max(dp[i-1], dp[i-2] + nums[i])

        return dp[n-1]

时间复杂度:O(n),使用了一次循环遍历所有房屋。
空间复杂度:O(n),使用了长度为n的一维数组存储dp的值。

由于对于每次需要计算的第i个房屋来说,它只与前面的两个值有关,因此我们可以优化空间复杂度为O(1)。
以下为代码实现:

class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        if n == 1:
            return nums[0]

        a, b = nums[0], max(nums[0],nums[1])
        for i in range(2, n):
            a, b = b, max(b, a + nums[i])

        return b

时间复杂度:O(n),仍然是使用了一次循环。
空间复杂度:O(1),只使用了额外的两个变量存储数据。

3. 删除并获得点数

给你一个整数数组 nums ,你可以对它进行一些操作。

每次操作中,选择任意一个 nums[i] ,删除它并获得 nums[i] 的点数。之后,你必须删除 所有 等于 nums[i] - 1 和 nums[i] + 1 的元素。

开始你拥有 0 个点数。返回你能通过这些操作获得的最大点数

真题点击此处:740.删除并获得点数

解题方法:动态规划
思路:根据题意,在选择了元素 x 后,所有等于 x-1 或 x+1 的元素会从数组中删除。如果数组中仍然有多个值为 x 的元素,由于所有等于 x-1 或 x+1 的元素已经被删除,我们可以直接删除 x 并获得其点数。因此,若选择了 x,则所有等于 x 的元素也应一同被选择,以最大化获得点数。我们可以用一个数组 sum 记录数组 nums 中所有相同元素之和,即 sum[x]=x*cx,其中 cx 表示元素 x 在数组中出现的次数。如果选择了 x,则可以获取 sum[x] 的点数,并且无法再选择 x-1 和 x+1。这样的话这题的解题思路就跟上题的打家劫舍是一样的了。
以下为代码实现:

class Solution:
    def deleteAndEarn(self, nums: List[int]) -> int:
        maxnum = max(nums)
        cnt = [0] * (maxnum + 1)

        for num in nums:
            cnt[num] += num

        a, b = cnt[0], cnt[1]
        for i in range(2,len(cnt)):
            c = max(cnt[i]+a, b)
            a, b = b, c
        return b

时间复杂度:时间复杂度:O(N+M),其中 N是数组 nums的长度,M 是 nums 中元素的最大值。
空间复杂度:O(M),使用了一个数组来存储cnt[num]的值。文章来源地址https://www.toymoban.com/news/detail-792758.html

到了这里,关于动态规划02-斐波那契类型二的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++算法 —— 动态规划(1)斐波那契数列模型

    每一种算法都最好看完第一篇再去找要看的博客,因为这样会帮你梳理好思路,看接下来的博客也就更轻松了。当然,我也会尽量在写每一篇时都可以让不懂这个算法的人也能边看边理解。 动规的思路有五个步骤,且最好画图来理解细节,不要怕麻烦。当你开始画图,仔细阅

    2024年02月10日
    浏览(46)
  • 【算法优选】 动态规划之斐波那契数列模型

    动态规划相关题目都可以参考以下五个步骤进行解答: 状态表⽰ 状态转移⽅程 初始化 填表顺序 返回值 后面题的解答思路也将按照这五个步骤进行讲解。 泰波那契序列 Tn 定义如下: T0 = 0, T1 = 1, T2 = 1, 且在 n = 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2 给你整数 n,请返回第 n 个泰波那契

    2024年02月05日
    浏览(56)
  • 算法刷题Day 38 动态规划理论基础+斐波那契数+爬楼梯

    动态规划的解题步骤: 确定 dp 数组(dp table)以及下标的含义 确定递推公式 dp 数组如何初始化 确定遍历顺序 举例推导 dp 数组 很基础

    2024年02月15日
    浏览(63)
  • Java数据结构与算法:动态规划之斐波那契数列

    大家好,我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编。在这寒冷的季节里,让我们一同探讨Java中的动态规划,重点关注解决问题的经典代表之一——斐波那契数列。 动态规划简介 动态规划是一种解决问题的数学方法,通常用于优化递归算法。它通过将问

    2024年01月22日
    浏览(48)
  • 数据结构与算法之动态规划: Leetcode 509. 斐波那契数 (Typescript版)

    斐波那契数 https://leetcode.cn/problems/fibonacci-number/ 描述 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是: 给定 n ,请计算 F(n) 。 示例 1 示例 2 示例 3 提示 0 = n = 30 算法实现 1 )方案 1 这

    2024年02月04日
    浏览(45)
  • 算法Day38 | 动态规划,509. 斐波那契数, 70. 爬楼梯, 746. 使用最小花费爬楼梯

    动态规划是一种解决问题的算法思想。它通常用于优化问题,其中要求找到一个最优解或最大化(最小化)某个目标函数。 动态规划的核心思想是 将问题分解成更小的子问题,并通过存储子问题的解来避免重复计算 。这样,可以通过解决子问题来构建原始问题的解。动态规

    2024年02月09日
    浏览(58)
  • 动态规划-斐波那契数

    斐波那契数是一个很好的熟悉和理解动态规划的例子,通过斐波那契数可以更好的理解动态规划的精髓,动态规划是后面的计算是如何借助于前面的计算结果来加快计算速度的。 斐波那契数和斐波那契数列其实可以看成是一道题,只不过两题的限制性条件稍微有差别 斐波那

    2024年02月14日
    浏览(36)
  • 【动态规划】是泰波那契数,不是斐波那契数

    Problem: 1137. 第 N 个泰波那契数 首先我们来解读一下本题的意思🔍 相信读者在看到【泰波那契数】的时候,不禁会联想到【斐波那契数】,它们呢是一对孪生兄弟,这个 泰波那契数 相当于是 斐波那契数 的加强版 我们首先可以来看到这个递推公式 Tn+3 = Tn + Tn+1 + Tn+2 ,读者可

    2024年02月08日
    浏览(48)
  • 【动态规划】斐波那契数列模型

    冻龟算法系列之斐波那契数列模型 动态规划(英语:Dynamic programming,简称 DP) ,是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质

    2024年02月09日
    浏览(65)
  • 算法训练第三十八天|动态规划理论基础、509. 斐波那契数 、70. 爬楼梯 、 746. 使用最小花费爬楼梯

    参考:https://programmercarl.com/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 动态规划是什么 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以 动态规划中每一个状态一定是由上一个状态推导出来的 ,这一

    2024年02月04日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包