动态规划_爬楼梯

70. 爬楼梯

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

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

示例 1:

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

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

提示:

1 <= n <= 45
当我们到达第三层楼梯时,我们有两种方法到达:从第一阶楼梯跳上去或者从第二阶楼梯跳上去
所以 f[3] = f[1] + f[2]  可以得到表达式 f[i] = f[i-1] + f[i-2]

def climbStairs(self, n: int) -> int:
        f = [0] *(n+1)
        f[0] = f[1] = 1
        for i in range(2,n+1):
            f[i] = f[i-1] + f[i-2]
        return f[n]

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 。
 

提示:

2 <= cost.length <= 1000
0 <= cost[i] <= 999
cost长度为n,而最后一个n表示向上爬需要花费的费用,所以实际上最后一层为 n 阶的顶层,所以f的长度为 n+1,求的是 n+1的值
因为可以从第0层和第1层开始爬,所以第0层和第1层 的初始值为0
当我们到达第i层时,我们可以是从第i-1层上来的,也可以是 从i-2层上来

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

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
   提示: • 1 <= nums.length <= 200 • 1 <= nums[i] <= 1000 • nums 中的所有元素 互不相同 • 1 <= target <= 1000
本题也是爬楼梯典型的题,目标为target阶阶梯,每次可以爬nums[i], 0 <= i <= len(nums) -1

class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        f = [0]*(target+1)
        f[0] = 1
        for i in range(1,target+1):
            f[i] = sum([f[i-x] for x in nums if i>=x])
        return f[target]

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

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

将 ‘0’ 在字符串末尾添加 zero 次。
将 ‘1’ 在字符串末尾添加 one 次。
以上操作可以执行任意次。

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

请你返回满足以上要求的 不同 好字符串数目。由于答案可能很大,请将结果对 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" 。
 

提示:

1 <= low <= high <= 105
1 <= zero, one <= low
class Solution:
    def countGoodStrings(self, low: int, high: int, zero: int, one: int) -> int:
        f = [0]*(high + 1)
        f[0] = 1
        for i in range(1,high+1):
            if i >= zero and i >= one:
                f[i] = f[i-zero] + f[i-one]
            elif i >= zero:
                f[i] = f[i-zero]
            elif i >= one:
                f[i] = f[i-one]
        ans = sum(f[i] for i in range(low,high+1))
        return ans %(10**9+7)

2266. 统计打字方案数

Alice 在给 Bob 用手机打字。数字到字母的 对应 如下图所示。
在这里插入图片描述
为了 打出 一个字母,Alice 需要 按 对应字母 i 次,i 是该字母在这个按键上所处的位置。

比方说,为了按出字母 ‘s’ ,Alice 需要按 ‘7’ 四次。类似的, Alice 需要按 ‘5’ 两次得到字母 ‘k’ 。
注意,数字 ‘0’ 和 ‘1’ 不映射到任何字母,所以 Alice 不 使用它们。
但是,由于传输的错误,Bob 没有收到 Alice 打字的字母信息,反而收到了 按键的字符串信息 。

比方说,Alice 发出的信息为 “bob” ,Bob 将收到字符串 “2266622” 。
给你一个字符串 pressedKeys ,表示 Bob 收到的字符串,请你返回 Alice 总共可能发出多少种文字信息 。

由于答案可能很大,将它对 10**9 + 7 取余 后返回。

示例 1:

输入:pressedKeys = "22233"
输出:8
解释:
Alice 可能发出的文字信息包括:
"aaadd", "abdd", "badd", "cdd", "aaae", "abe", "bae" 和 "ce" 。
由于总共有 8 种可能的信息,所以我们返回 8 。
示例 2:

输入:pressedKeys = "222222222222222222222222222222222222"
输出:82876089
解释:
总共有 2082876103 种 Alice 可能发出的文字信息。
由于我们需要将答案对 10**9 + 7 取余,所以我们返回 2082876103 % (10**9 + 7) = 82876089 。
 

提示:

1 <= pressedKeys.length <= 105
pressedKeys 只包含数字 '2' 到 '9' 。
本题有2个关键点:
1、求出每段相同字符的数量
2、类似于爬楼梯,如果一段字符长度为n,那么对于数字 1 2 3 4 5 6 8,相当于每次可以爬 1/2/3步,爬到n步时,一共有多少种爬法,如果是数字79 那么相当于每次可以爬 1/2/3/4class Solution:
    def countTexts(self, pressedKeys: str) -> int:
        num_count = []
        n = len(pressedKeys)
        i = j = i_count = 0
        while i <= n -1 and j <= n-1:
            if  pressedKeys[j] == pressedKeys[i]:
                i_count += 1
                if j == n -1:
                     num_count.append([pressedKeys[i],i_count])
                j += 1
            else:
                num_count.append([pressedKeys[i],i_count])
                i_count = 0
                i = j
        cal_list = []
        for x in num_count:
            s, t = x[0], x[1]
            f = [0] *(t+1)
            f[0] = 1
            for i in range(1,t+1):
                if s in ['7','9']:
                    f[i] = sum(f[i-m] for m in range(1,5) if i >= m)
                else:
                    f[i] = sum(f[i-m] for m in range(1,4) if i >= m)
            cal_list.append(f[t])
        f_rel = 1
        for i in cal_list:
            f_rel = f_rel * i
        return f_rel % (10**9 + 7)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值