知识储备--基础算法篇-动态规划

1.前言

第一次接触动态规划,不知道具体什么意思,做了题才发现动态规划就是把大问题变成小问题,并解决了小问题重复计算的方法称为动态规划。比如上楼梯,一次上一阶或二阶,求有多少种算法,就可以拆成最后一阶的方法数等于前一阶的方法数加前两阶的方法数,这就是递归算法。但是这样往往会超出时间限制,因为里面有大量的重复,比如一共5阶,F(5)=F(4)+F(3),其中F(4)=F(3)+F(2),这里面F(3)就被重复计算了,这时我们需要将算好的值储存下来,避免重复计算,这就是记忆递归算法。

递归是一种程序的实现方式:函数的自我调用。

动态规划:是一种解决问 题的思想,大规模问题的结果,是由小规模问 题的结果运算得来的。动态规划可用递归来实现(Memorization Search)

使用场景

满足两个条件

  • 满足以下条件之一

    • 求最大/最小值(Maximum/Minimum )
    • 求是否可行(Yes/No )
    • 求可行个数(Count(*) )
  • 满足不能排序或者交换(Can not sort / swap )

2.实战

2.1第70题

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

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

心得:很经典的题目,用动态规划,之前一直有个疑问就是,递归的顺序是怎么执行的,是同时计算同一层的两个F(n-1)和F(n-2),还是先计算位于前面的F(n-1),直到算出F(n-1)再计算F(n-2),这次我直接打印出来了,发现是先递归计算出位于前面的F(n-1),这时该储存的已经储存好了,后面计算F(n-2)时就不会重复计算了。

改成自下而上dp(动态规划)

python 复制代码
class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n==1:
            return 1
        elif n==2:
            return 2
        dp = [0]*(n+1)
        dp[1] = 1
        dp[2] = 2
        for i in range(3,n+1):
            dp[i] = dp[i-1] + dp[i-2]
        
        return dp[n]

因为该问题符合斐波那契数列,直接算

python 复制代码
class Solution(object):
    def climbStairs(self, n):
        """
        :type n: int
        :rtype: int
        """
        a = b = 1
        for i in range(2, n + 1):
            a, b = b, a + b
        return b

2.2第118题

给定一个非负整数 numRows 生成「杨辉三角」的前 *numRows*行。

在「杨辉三角」中,每个数是它左上方和右上方的数的和。

python 复制代码
class Solution(object):
    def generate(self, numRows):
        """
        :type numRows: int
        :rtype: List[List[int]]
        """
        if numRows==1:
            return [[1]]
        result = [[1]]
        for i in range(2,numRows+1):
            current = [1]*i
            if i>2:
                for j in range(1,i-1):
                    current[j] = result[i-2][j-1]+result[i-2][j]
            result.append(current)
        
        return result

2.3第198题

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

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

心得:看到这种求最大金额的题目就要想到动态规划,动态规划就是要把大问题分为一个个的小问题来进行解决。这道题就是,可以把最高金额的问题分为求局部最高金额的问题,然后再递归就能解决了。感觉像是上楼梯的升级题目,多了一个max判断。自左往右。也可以使用递归,自右往左。

python 复制代码
class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            return nums[0]
        elif len(nums) == 2:
            return max(nums[0], nums[1])
        dp = [0]*(len(nums)+1)
        dp[1] = nums[0]
        dp[2] = nums[1]
        for i in range(3,len(nums)+1):
            dp[i] = max(dp[i-3] + nums[i-1], dp[i-2] + nums[i-1])
        return max(dp[-1], dp[-2])
相关推荐
用户405478783748242 分钟前
深度学习笔记 - 使用YOLOv5中的c3模块进行天气识别
算法
十七算法实验室1 小时前
Matlab实现麻雀优化算法优化随机森林算法模型 (SSA-RF)(附源码)
算法·决策树·随机森林·机器学习·支持向量机·matlab·启发式算法
黑不拉几的小白兔1 小时前
PTA部分题目C++重练
开发语言·c++·算法
迷迭所归处1 小时前
动态规划 —— dp 问题-买卖股票的最佳时机IV
算法·动态规划
chordful1 小时前
Leetcode热题100-32 最长有效括号
c++·算法·leetcode·动态规划
_OLi_2 小时前
力扣 LeetCode 459. 重复的子字符串(Day4:字符串)
算法·leetcode·职场和发展·kmp
材料苦逼不会梦到计算机白富美2 小时前
线性DP 区间DP C++
开发语言·c++·动态规划
Romanticroom2 小时前
计算机23级数据结构上机实验(第3-4周)
数据结构·算法
白藏y2 小时前
数据结构——归并排序
数据结构·算法·排序算法
ahadee2 小时前
蓝桥杯每日真题 - 第12天
c++·vscode·算法·蓝桥杯