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

动态规划练习题①

70. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 12 个台阶。你有多少种不同的方法可以爬到楼顶呢?

示例 1:

输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

示例 2:

输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

class Solution:
    def climbStairs(self, n: int) -> int:
        """
        1. 递归
        假设刚开始站在下标为0的台阶,现在要爬到下标为n的台阶
        dfs(i)表示爬到下标为n的台阶的方法数
        dfs(i)可以表示为dfs(i-1)与dfs(i-2)的台阶总和,这样就分成了子问题
        
        def dfs(i):
            # dfs(0)只有一种方法 ———— 不爬;dfs(1)有一种方法,也就是从坐标为0爬一步到坐标为1
            if i<=1:
                return 1
            return dfs(i-1)+dfs(i-2)
        return dfs(n)
        """

        """
        2. 记忆化搜索
        cache=[-1]*(n+1)
        def dfs(i):
            if i<=1:
                return 1
            if cache[i]!=-1:
                return cache[i]
            res=dfs(i-1)+dfs(i-2)
            cache[i]=res
            return res
        return dfs(n)
        """

        """
        3. 递推
        dp=[0]*(n+1)
        dp[0]=1
        dp[1]=1
        for i in range(2,n+1):
            dp[i]=dp[i-2]+dp[i-1]
        return dp[-1]
        """

        """
        4. 优化空间复杂度为O(1)
        i=1
        j=1
        for _ in range(2,n+1):
            k=i+j
            i=j
            j=k
        return k
        """


746. 使用最小花费爬楼梯

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

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

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

示例 1:

输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。

示例 2:

输入:cost = [1,100,1,1,1,100,1,1,100,1]
输出:6
解释:你将从下标为 0 的台阶开始。
- 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。
- 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。
- 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。
- 支付 1 ,向上爬一个台阶,到达楼梯顶部。
总花费为 6 。

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        """
        1. 递推
        dfs(i)为爬到下标为n台阶时的最小花费

        n=len(cost)
        def dfs(i):
            if i<=1:
                return 0
            return min(dfs(i-1)+cost[i-1],dfs(i-2)+cost[i-2])
        return dfs(n)
        """

        """
        2. 记忆化搜索
        n=len(cost)
        cache=[-1]*(n+1)
        def dfs(i):
            if i<=1:
                return 0
            if cache[i]!=-1:
                return cache[i]
            res=min(dfs(i-1)+cost[i-1],dfs(i-2)+cost[i-2])
            cache[i]=res
            return res
        return dfs(n)
        """

        """
        3. 动态规划
        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[-1]
        """

        """
        4. 优化空间复杂度为O(1)
        n=len(cost)
        i,j=0,0
        for x in range(2,n+1):
            k=min(i+cost[x-2],j+cost[x-1])
            i=j
            j=k
        return k
        """


377. 组合总和 Ⅳ

给你一个由 不同 整数组成的数组 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

class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        """
        1. 递归
        dfs(i)表示为总和为target的元素组合的个数
        将此题抽象为爬楼梯,现在要找出爬到target阶的方法总数
        比如当使用了nums[0]时,就变成了要找出爬到target-nums[0]阶的方法总数的子问题
        当target减到0时,此时就找到了一种方法,返回1

        def dfs(target):
            if target == 0:
                return 1
            tol = 0
            for num in nums:
                if num <= target:
                    tol += dfs(target - num)
            return tol
        return dfs(target)
        """

        """
        2. 记忆化搜索
        n = len(nums)
        cache = [0] * (target + 1)
        def dfs(target):
            if target == 0:
                return 1
            if cache[target] > 0:
                return cache[target]
            tol = 0
            for num in nums:
                if num <= target:
                    tol += dfs(target - num)
            cache[target] = tol
            return tol
        return dfs(target)
        """

        """
        3. 递推
        dp[i]表示目标值为i的方法总和

        n = len(nums)
        dp = [0] * (target + 1)
        dp[0] = 1  # 初始化,目标值为0只有一种组合,即空集
        for i in range(1, target + 1):
            for num in nums:
                if num <= i:  # 如果当前数字小于目标值,则等于dp[i-num]的总和
                    dp[i] += dp[i - num]
        return dp[-1]
        """


2466. 统计构造好字符串的方案数

给你整数 zeroonelowhigh ,我们从空字符串开始构造一个字符串,每一步执行下面操作中的一种:

  • '0' 在字符串末尾添加 zero 次。
  • '1' 在字符串末尾添加 one 次。

以上操作可以执行任意次。

如果通过以上过程得到一个 长度lowhigh 之间(包含上下边界)的字符串,那么这个字符串我们称为 字符串。

请你返回满足以上要求的 不同 好字符串数目。由于答案可能很大,请将结果对 109 + 7 取余 后返回。

示例 1:

输入:low = 3, high = 3, zero = 1, one = 1
输出:8
解释:
一个可能的好字符串是 "011" 。
可以这样构造得到:"" -> "0" -> "01" -> "011" 。
从 "000" 到 "111" 之间所有的二进制字符串都是好字符串。

示例 2:

输入:low = 2, high = 3, zero = 1, one = 2
输出:5
解释:好字符串为 "00" ,"11" ,"000" ,"110" 和 "011" 。

class Solution:
    def countGoodStrings(self, low: int, high: int, zero: int, one: int) -> int:
        """
        1. 递归
        好字符串的数目分别为字符串长度为low,low+1...high-1,high的个数总和
        在求每一个长度的字符串个数时,可以将此抽象为爬楼梯
        假设字符串个数为target,我们要求爬到第target阶的方法数

        s = [zero * "0", one * "1"]
        def dfs(target):
            if target == 0:
                return 1
            tol = 0
            for i in s:
                if len(i) <= target:
                    tol += dfs(target - len(i))
            return tol
        count = 0
        for i in range(low, high + 1):
            count += dfs(i)
        return count % (10**9 + 7)
        """

        """
        2. 记忆化搜索
        s = [zero * "0", one * "1"]
        def dfs(target):
            if target == 0:
                return 1
            if cache[target] != -1:
                return cache[target]
            tol = 0
            for i in s:
                if len(i) <= target:
                    tol += dfs(target - len(i))
            cache[target] = tol
            return tol
        count = 0
        for i in range(low, high + 1):
            cache = [-1] * (i + 1)
            count += dfs(i)
        return count % (10**9 + 7)
        """

        """
        3. 递推
        s = [zero * "0", one * "1"]
        tol = 0
        for i in range(low, high + 1):
            dp = [0] * (i + 1)
            dp[0] = 1
            for j in range(1, i + 1):
                for k in s:
                    if len(k) <= j:
                        dp[j] += dp[j - len(k)]
            tol += dp[-1]
        return tol % (10**9 + 7)
        """

        # 上面的代码只能过30/36

        # 递推版本二
        # dp[i]为目标长度为i时,选择zero个0的方法个数 + 选择one个1的方法个数
        dp = [0] * (high + 1)
        dp[0] = 1
        for i in range(1, high + 1):
            if i >= zero:
                dp[i] += dp[i - zero]
            if i >= one:
                dp[i] += dp[i - one]
        return sum(dp[low:]) % (10**9 + 7)


http://www.dtcms.com/a/107273.html

相关文章:

  • 蓝桥杯 web 灯的颜色变化(Dom操作及样式动态修改、浏览器解析顺序、定时器)
  • 计算机科学基础设施之数学:科研工具、资源与环境详介
  • qt.qpa.xcb: could not connect to display解决方法
  • Keil5烧录后STM32不自动运行?必须复位才能启动的终极解决方案
  • element-plus中,Upload上传组件的使用 + 后端处理
  • DMA在SPI和I2C通信中的应用详解
  • 解锁异步编程新姿势:CompletableFuture 深度探秘
  • java根据集合中对象的属性值大小生成排名
  • [NOIP 1999 提高组] 导弹拦截
  • C++ STL简单的几个容器
  • I²C总线高级特性与故障处理分析
  • 【leetcode100】每日温度
  • OpenCV 从入门到精通(day_04)
  • 面向对象
  • python实现简单fast-cgi服务,对接到nginx
  • 蓝桥云客 刷题统计
  • 持续集成与Jenkins安装使用教程
  • 分布式锁方案-Redisson
  • Linux命令-tar
  • 使用 MapReduce 进行高效数据清洗:从理论到实践
  • Linux内核中ARP协议的实现与dev_addr字段的作用
  • LabVIEW 调用 Python 函数
  • SAP-ABAP:ABAP `LEAVE LIST-PROCESSING` 深度解析
  • 天梯赛 L2-023 图着色问题
  • ai prompt工程师认证
  • AT_abc306_b [ABC306B] Base 2
  • 【工具变量】全国分省低空经济高质量发展数据(2012-2023年)
  • Word 插入无页眉页码的空白页(即插入奇数页)
  • WebSocket connection failed 解决
  • 基于机器学习的三国时期诸葛亮北伐失败因素量化分析