leetcode动态规划(基础版)746. 使用最小花费爬楼梯

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

代码思路:

  使用动态规划的思想,定义一个长度为n的dp数组,其中dp[i]表示到达第i个台阶所需的最小花费。由于可以从下标为0或1的台阶开始爬楼梯,所以dp[0]和dp[1]的值分别为cost[0]和cost[1]。从第2个台阶开始,每次计算dp[i]时,可以选择从dp[i-1]或dp[i-2]的位置跳上来,所以dp[i]的值为min(dp[i-1], dp[i-2]) + cost[i]。最后返回dp[-1]和dp[-2]中的较小值即可。

也就是说比较它的前一阶和前两阶加现在阶的花费,类似于70的爬楼梯,只是之前要的是爬上楼梯有多少种方法,而现在要的是具体花销。但有类似之处在于现在所求的这一个都是之前的累加。这就是动态规划,我们熟悉的递归调用在于从上到下,比如计算阶乘n!=(n-1)!*n。这种情况下会一直分解到1!再一层层乘上来,如下:

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)

  但是动态规划是一种自下而上的解决问题的方法,它将问题分解成多个子问题,并且保存子问题的解,以便后续使用。动态规划通常需要用到一个表格来保存子问题的解,然后根据表格中的数据计算出大问题的解。

  在这个例子中,我们将阶乘问题分解成许多小问题,例如计算4的阶乘需要先计算3的阶乘,计算3的阶乘需要先计算2的阶乘,以此类推。通过使用dic字典来存储已经计算过的阶乘值,我们可以避免重复计算,从而提高程序的效率。

  这个函数使用了一个名为dic的字典来存储已经计算过的阶乘值。如果n在dic中已经存在,那么函数直接返回dic[n]的值。否则,函数计算n的阶乘并将结果存储在dic[n]中,然后返回dic[n]的值。

  这个函数的时间复杂度是O(n),因为它只需要计算每个n值一次。使用动态规划的好处是可以避免重复计算,从而提高程序的效率。

python
def factorial(n, dic={}):
    if n == 0:
        return 1
    if n in dic:
        return dic[n]
    dic[n] = n * factorial(n-1, dic)
    return dic[n]

  可以看到,递归的方式是自上而下地解决问题,每次都需要重新计算子问题的解,而动态规划的方式是自下而上地解决问题,每次都利用之前计算的结果来计算当前的结果。 

这是我的初始代码,存在多个错误,下面逐一列出:

  1. 第2行的 cost[] = input() 应该删除,因为 cost 已经作为参数传入函数中了,不需要再次输入。

  2. 第3行的 n=len(cost[]) 应该改为 n=len(cost),因为 cost 是一个列表,不需要再加上 []

  3. 第4行的 dp[]=0*n 应该改为 dp=[0]*n,因为 dp 是一个列表,需要用 * 运算符来初始化。

  4. 第10行的 if dp[i] <= dp[i+1]:else: 后面的 return 语句应该移动到循环结束后,因为需要遍历完整个列表才能确定最小代价。

  5. 第13行的 print sum(dp[]) 应该改为 print(sum(dp)),因为 sum() 是一个函数,需要用括号来调用。

改进后成了这样,但是第一个测试用例通过之后没有通过第二个测试用例。原因在于没有保存之前的花销,导致以下结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值