IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【算法模板】动态规划(基础DP篇) -> 正文阅读

[数据结构与算法]【算法模板】动态规划(基础DP篇)

【算法模板】动态规划(基础DP篇)

📒博客首页:铁甲小宝同学 📒

🌞文章目的:动态规划基础篇分享🌞

🙏博主也在学习阶段,如若发现问题,请告知,非常感谢🙏

💗同时也非常感谢各位小伙伴们的支持💗

🌈每日一语:你相信光吗? 🌈

将过去和羁绊全部丢弃,不好吝惜那为梦想留下的泪水 。 ——路飞

在这里插入图片描述

前言

博主因最近刷的大部分都是动态规划的算法题,所以也把博主所刷的心得和习题在本篇文章中总结分享给大家,并且希望能帮助到大家。

感谢: 感谢csdn、力扣、代码随想录等平台和大佬们提供的习题和题解!!


什么是动态规划?

动态规划 (英语:Dynamic programming,简称 DP),是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题。(百度百科得到的答案)

简单的就是说:用简单的方法来解决复杂的问题!

核心思想:

动态规划的核心就是 有记忆,减少不必要的计算!

熊猫人 max,胖版熊猫人 - 熊猫头斗图表情包 _熊猫人_斗图表情

动态规划的做题方法

一般我们在做动态规划这种题的时候一般会有一下这几个步骤:

  • 定义一个的dp数组。
  • dp数组的初始化。
  • 列举动态规划推导公式。
  • 进行循环遍历逐步改变dp数组的值,直道循环结束能获取我们所需要的值即可。

我们只要上述的几个步骤没有出现什么问题的话,那么这个这个题也就是手到擒拿了!

而上述步骤中比较难的就是 动态规划推导公式 的推导,一般在做题时我们很容易的知道这个题是用动态规划来解决这个问题。但是每次就会卡到动态规划推导公式这个地方(不要问我为什么5555)。所以这个也是我们需要提高的地方!!!

给大家一些 建议 ,在做动态规划题的时候 一定要自己推导自己的动态规划推导公式 ,就算写不出来我们在看题解的时候也可以那我们自己推导出来的公式和官方的公式进行一个对比,每次在做题的时候只要能保证这点,则以后的进步就会越来越大!!!


一维DP

简介

在上面我们已经知道了什么是 DP 了,那么什么又是 一维DP 呢?

一维DP:

通常的讲 一维DP 就是通过一维的数组来满足 推导公式 的一个求解。

int[] dp = new int[10];//则表示创建了一个长度为10的一维DP数组。

//例如:推导公式
dp[i] = max(dp[i - 2] + dp[i - 1] , dp[i])//这个就是一个比较简单的一维DP推导公式!

走进一维DP

上述中我们知道了什么是 一维DP ,那我们就要来走进这个它,并且征服它!同学们来看下面的例题吧。

熊猫何苦为难熊猫(熊猫头)_熊猫_何苦_为难表情

例题:

509. 斐波那契数

题目:

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 01 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

示例:

输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1

做题步骤:

还记得我们第一步需要怎么来分析的吗?

第一步我们需要确定这题的 DP 数组该怎么去创建?

第二步需要我们推导出本题的 DP 公式。

第三步进行循环得到我们需要的结果。

思路:

通过做题步骤我们能知道这个 DP数组 的长度是 n + 1 (因为需要从0开始到n,所以长度也就是 n + 1

题目所说从 1 后面开始每一项的数字都是前两项的和。通过解析这句话我们能知道我们的 循环是从2开始,到n结束 。而推导公式则就是:

dp[i] = dp[i - 1] + dp[i - 2]

当我们完成上述的步骤时接下来就是将这题给实现了。

代码:

Python版本:

class Solution:
    def fib(self, n: int) -> int:
        if n < 2:
            return n
        dp = [0]* (n + 1)
        dp[1] = 1
        for i in range(2 , n + 1):
            dp[i] = dp[i - 1] + dp[i - 2]
        return dp[n]

Java版本:

class Solution {
    public int fib(int n) {
        if (n == 0) return 0;
        if (n == 1) return 1;
        int[] dp = new int[n + 1];
        dp[1] = 1;
        for (int i = 2; i < n + 1; i++){
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

我们做了一个比较简单的DP题,那我们再来看另外一个简单的DP问题吧

题目:

746. 使用最小花费爬楼梯

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

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

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

示例:

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

做题步骤:

DP数组 的创建。

推导出本题的 DP 公式。

进行循环。

思路:

在题目的含义中我们已经知道了 用最小的花费来达到顶楼! 则我们需要创建的 DP数组 长度就为 n + 1 (第n 个下标代表的是楼顶)。则也能得到动态规划的公式和循环的开始点和结束点!

动态规划公式:

dp[i] = min(dp[i-1]+cost[i-1],cost[i-2]+dp[i-2])//4开始的循环公式
dp[i] = min(dp[i - 1] + cost[i - 1], cost[i - 2] )//当i是等于3的时候判断方程式
dp[i] = min(cost[i - 1], cost[i - 2])//等于2的时候的一个公式

代码:

Python版本

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp = [0 for i in range(len(cost)+1)]
        
        for i in range(2,len(cost)+1):
            if i ==3 :
                dp[i] = min(dp[i - 1] + cost[i - 1], cost[i - 2] )
            elif i ==2 :
                dp[i] = min(cost[i - 1], cost[i - 2])
            else:
             dp[i] = min(dp[i-1]+cost[i-1],cost[i-2]+dp[i-2])
        return dp[len(cost)]

Java版本:

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int[] dp  = new int[cost.length + 1];
        for(int i = 2; i < cost.length + 1; i ++){
            if (i == 2){
                dp[i] = Math.min(cost[i - 1], cost[i - 2]);
            }
            else if (i == 3){
                dp [i] = Math.min(cost[i - 2] , dp[i - 1] + cost[i - 1]);
            }else{
                dp[i] = Math.min(cost[i - 1] + dp[i - 1] , cost[i - 2] + dp[i - 2]);
            }
        }
        return dp[cost.length];

    }
}

OK,例题看完了,接下来就是来看习题了哦!!!

模块练习题

题目
70 爬楼梯
整数拆分
不同的二叉搜索树
198 打家劫舍
213 打家劫舍 II
337 打家劫舍 III

蝴蝶结版熊猫头脸红 - 熊猫头蝴蝶结系列_蝴蝶结_熊猫头表情

二维DP

上述中我们了解了什么是一维DP,接下来就是简单的 二维DP

简介

什么是 二维DP 呢?

我们知道我们使用一个一维数组就是 一维DP ,那么我们在 一维DP 里面再套一个 一维DP数组 则这个就是一个 二维DP 。简单来说 二维DP 就是 一维DP 中再包含一个 一维DP

img

走进二维DP

题目:

62. 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

来源:力扣(LeetCode)

示例:

在这里插入图片描述

输入:m = 3, n = 7
输出:28

做题步骤:

我们能通过题目知道这是一个二维的空间,机器人能在这个二维空间经行下或右的移动,当然 二维DP 也是一样首先需要确定一个 DP数组 ,然后确定推导公式,最后循环并得到结果。

思路:

当然啦,二维DP 当然要定义二维数组,推导公式是按照自己的需要来的。

本题的二维数组则就是网格的长和宽:

int[][] dp = new intp[m][n];

因为机器人只能向下和向右移动:

一种是从 (i-1, j) 这个位置走一步到达

一种是从(i, j - 1) 这个位置走一步到达

所以我们能得到其走到每个格子的路径(左边界和上边界的起始值都是1)的推导公式:相邻的左格子和上格子相加。

dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 

循环则就需要嵌套循环,并且从(1,1)开始。

代码:

Python版本

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        dp = [[1]*n] + [[1]+[0] * (n-1) for _ in range(m-1)]
        #print(dp)
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[-1][-1]

Java版本:

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for(int k = 0; k < m; k ++){
            dp[k][0] = 1;
        }
        for(int l = 0; l < n; l ++){
            dp[0][l] = 1;
        }
        for (int i = 1; i < m; i++ ){
            for(int j = 1; j < n; j++){
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m-1][n-1];

    }
}

OK,下面是整理好的一些 二维DP 习题。

模块练习题

题目
63 不同路径 II
64. 最小路径和
72. 编辑距离

在这里插入图片描述

总结

OK,今天的分享就到这里啦,希望本篇文章能够帮助屏幕前的你!大家看完不要忘了来个三联,这将会是博主最大的动力!!!

溜了溜了,吃饭去了888888。

下期见!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:36:03  更:2022-04-04 12:36:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:04:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码