算法篇——动态规划

核心思想:

将问题分解为重叠的子问题,并储存子问题的解(使用字典、数组或哈希表),避免重复计算,从而提高效率。

题目特点:重叠子问题(特殊地,是最优子结构)

比如:斐波那契数列问题中,递归求F(5),需要多次计算F(3);

最短路径问题中,若从A到C的最优路径包含B,则A到B和B到C也必然是最优的。

两种实现方式:

自顶向下(递归+储存记忆,将大问题逐步分解,子问题的解储存在字典里):

class Solution(object):
    # 把momory作为类属性
    memory = {}

    def fib(self, n):
        # 如果已经在记忆里储存,则直接返回,不用再重复计算
        if n in self.memory: 
            return self.memory[n]

        if n<=1:
            return n

        self.memory[n] = self.fib(n-1)+self.fib(n-2)
        return self.memory[n]

自底向上(迭代+储存记忆,先解决小问题再解决大问题,小问题的解储存在数组里):

class Solution(object):
    def fib(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp = [0,1] # 动态规划数组,初始值相当于递归里遇到终止条件能直接返回的值

        for i in range(2,n+1):
            dp.append(dp[i-1]+dp[i-2])
        
        return dp[n]

解题步骤:

1、定义状态(dp[i]表示什么)

2、写状态转移方程(由局部最优一直推到全局最优,所以从初始截断到当前位置来考虑即可,后面的先不管)

3、确定初始状态(起码两个)

3、用递归or迭代解题

比如:“打家劫舍”求数组中不相邻元素组合,使值的和最大

(1)定义状态:设dp[i]表示从第0到第i个中元素组合的最优解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值