动态规划相关题目

文章目录

  • 1.动态规划理论基础
  • 2.斐波那契数
  • 3.爬楼梯
  • 4.使用最小花费爬楼梯
  • 5.不同路径
  • 6.不同路径 II
  • 7. 整数拆分
  • 8. 不同的二叉搜索树

1.动态规划理论基础

1.1 什么是动态规划?

动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的。

1.2 动态规划的解题步骤

动态规划五部曲:

  • 确定dp数组(dp table)以及下标的含义
  • 确定递推公式
  • dp数组如何初始化
  • 确定遍历顺序
  • 举例推导dp数组

2.斐波那契数

题目:
在这里插入图片描述
思路:
状态转移方程 dp[i] = dp[i - 1] + dp[i - 2]

代码:

class Solution:
    def fib(self, n: int) -> int:
       
        # 排除 Corner Case
        if n == 0:
            return 0
        
        # 创建 dp table 
        dp = [0] * (n + 1)

        # 初始化 dp 数组
        dp[0] = 0
        dp[1] = 1

        # 遍历顺序: 由前向后。因为后面要用到前面的状态
        for i in range(2, n + 1):

            # 确定递归公式/状态转移公式
            dp[i] = dp[i - 1] + dp[i - 2]
        
        # 返回答案
        return dp[n]

3.爬楼梯

题目:
在这里插入图片描述
思路:
递推公式dp[i] = dp[i - 1] + dp[i - 2]

代码:

class Solution:
    def climbStairs(self, n: int) -> int:
        if n == 1:return 1
        if 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 - 2] + dp[i-1]
        return dp[n]

4.使用最小花费爬楼梯

题目:
在这里插入图片描述
思路:
dp[i]的定义:到达第i台阶所花费的最少体力为dp[i]。
递推公式:
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
:楼顶的下标是n+1

代码:

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp = [0] * (len(cost) + 1)
        # dp[0] = 0  # 初始值,表示从起点开始不需要花费体力
        # dp[1] = 0  # 初始值,表示经过第一步不需要花费体力
        
        for i in range(2, len(cost) + 1):
            # 在第i步,可以选择从前一步(i-1)花费体力到达当前步,或者从前两步(i-2)花费体力到达当前步
            # 选择其中花费体力较小的路径,加上当前步的花费,更新dp数组
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
        
        return dp[len(cost)]  # 返回到达楼顶的最小花费

5.不同路径

题目:
在这里插入图片描述
思路:
dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。

递推公式:dp[i][j] = dp[i - 1][j] + dp[i][j - 1]

如何初始化呢,首先dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理。

代码:

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        # 创建一个二维列表用于存储唯一路径数
        dp = [[0] * n for _ in range(m)]
        
        # 设置第一行和第一列的基本情况
        for i in range(m):
            dp[i][0] = 1
        for j in range(n):
            dp[0][j] = 1
        
        # 计算每个单元格的唯一路径数
        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[m - 1][n - 1]

6.不同路径 II

题目:
在这里插入图片描述
思路:
【注】边界初始化时要注意障碍物,还要考虑到起始点和终止点的障碍物
当网格中没有障碍物时,执行递推公式。

代码:

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        m = len(obstacleGrid)
        n = len(obstacleGrid[0])
        if obstacleGrid[0][0] == 1 or obstacleGrid[m - 1][n - 1] == 1:
            return 0
        dp = [[0] * n for _ in range(m)]
        i = 0
        j = 0
        while i < m and obstacleGrid[i][0] != 1:
            dp[i][0] = 1
            i += 1
        while j < n and obstacleGrid[0][j] != 1:
            dp[0][j] = 1
            j += 1
        for i in range(1,m):
            for j in range(1,n):
                if obstacleGrid[i][j] != 1:
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
        return dp[m-1][n-1]

7. 整数拆分

题目:
在这里插入图片描述
思路:
dp[i]:分拆数字i,可以得到的最大乘积为dp[i]

递推公式:dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});

代码:

class Solution:
    def integerBreak(self, n: int) -> int:
        dp = [0] * (n + 1)
        for i in range(2,n+1):
            j = 1
            while j <= i // 2:
                dp[i] = max(j * (i - j),j*dp[i - j],dp[i])
                j += 1
        return dp[n]

8. 不同的二叉搜索树

题目:
在这里插入图片描述
思路:
思路详解

代码:

class Solution:
    def numTrees(self, n: int) -> int:
        dp = [0] * (n + 1)  # 创建一个长度为n+1的数组,初始化为0
        dp[0] = 1  # 当n为0时,只有一种情况,即空树,所以dp[0] = 1
        for i in range(1, n + 1):  # 遍历从1到n的每个数字
            for j in range(1, i + 1):  # 对于每个数字i,计算以i为根节点的二叉搜索树的数量
                dp[i] += dp[j - 1] * dp[i - j]  # 利用动态规划的思想,累加左子树和右子树的组合数量
        return dp[n]  # 返回以1到n为节点的二叉搜索树的总数量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/501418.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c语言中的联合体和枚举

这篇文章总结一下c语言中的联合体和枚举。看看这两个东西到底是什么。大家一起学习。 文章目录 一、联合体1.联合体类型的声明。2.联合体的大小。3.相同成员的结构体和联合体对比4.联合体大小的计算。 二、枚举类型1.枚举类型的声明。2.枚举类型的优点。枚举类型的使用。 一、联…

gitee规范团队 代码提交

1.团队开会规范 使用 插件 &#xff1a; git Commit Message Helper 插件进行代码提交前规范 2.gitee代码仓库断控制&#xff0c;上面只是规范了程序员开发端&#xff1b;但是gitee也要管理控制&#xff1b;正则根据每个公司的不同来进行。

民航电子数据库:CAEMigrator迁移数据库时总是卡死

目录 一、场景二、异常情况三、排查四、应急方案 一、场景 1、对接民航电子数据库 2、将mysql数据库迁移到cae数据库 3、使用CAEMigrator迁移工具进行数据库迁移时&#xff0c;该工具会卡死&#xff08;不清楚是否是部署cae服务的服务器资源导致&#xff09; 二、异常情况 …

iOS - Runloop介绍

文章目录 iOS - Runloop介绍1. 简介1.1 顾名思义1.2. 应用范畴1.3. 如果没有runloop1.4. 如果有了runloop 2. Runloop对象3. Runloop与线程4. 获取Runloop对象4.1 Foundation4.2 Core Foundation4.3 示例 5. Runloop相关的类5.1 Core Foundation中关于RunLoop的5个类5.2 CFRunL…

报错[Vue warn]: $listeners is readonly. $attrs is readonly.怎么解决?

代码也没有逻辑错误&#xff0c;但是报错 [Vue warn]: $listeners is readonly. $attrs is readonly. 情况1&#xff1a;多处声明了new Vue&#xff0c;解决方案&#xff1a;删除一个&#xff0c;用全局变量引用同一个Vue 情况2&#xff1a;import Vue from Vue;第二个Vue首字…

跳跃游戏-java

题目描述: 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 解题思想: …

蓝桥OJ 3500阶乘求和(找规律)

阶乘求和 做这道题两个循环到202320232023肯定会超时间。 但是可以发现算到将近40的阶乘时&#xff0c;后9位的答案就已经可以确定了。 #include<bits/stdc.h> using namespace std; using ll long long; const ll p 1e9; int main() {ll res 0;for (int i 1; i &l…

真实sql注入以及小xss--BurpSuite联动sqlmap篇

前几天漏洞检测的时候无意发现一个sql注入 首先我先去网站的robots.txt去看了看无意间发现很多资产 而我意外发现admin就是后台 之后我通过基础的万能账号密码测试or ‘1‘’1也根本没有效果 而当我注入列的时候情况出现了 出现了报错&#xff0c;有报错必有注入点 因此我…

数据结构——线性表(二)

线性表顺序存储结构的优缺点 优点:1.无须为表示表中元素之间的逻辑关系而增加额外的存储空间 2.可以快速的存取表中的任一位置的元素 缺点:1.插入和删除操作需要移动大量的元素 2.当线性表长度变化较大的时候,难以确定存储空间的容量 3.造成存储空间的"碎片" 所以…

Golang线上内存爆掉问题排查(pprof)

Golang线上内存爆掉问题排查&#xff08;pprof&#xff09; 1 问题描述 某天&#xff0c;售后同事反馈&#xff0c;我们服务宕掉了&#xff0c;客户无法预览我们的图片了。 我们预览图片是读取存储在我们S3服务的数据&#xff0c;然后返回给前端页面展示。因为客户存在几百M的…

【Python】你真的了解爬虫吗?初识爬虫

什么是爬虫&#xff1f; 简单来说&#xff1a;代替人去模拟浏览器进行网页操作。 它能解决什么问题&#xff1f; 自动高效地获取互联网中我们感兴趣的信息并为我们所用。 即&#xff1a;为其他程序提供数据源 如搜索引擎(百度、Google等)、数据分析、大数据等等。 爬虫的分…

基于MS的水分子径向分布函数(RDF)计算

​​​​​​ 构建水分子结构 新建一个3D Atomistic.xsd文件&#xff0c;命名为H2O&#xff0c;点击 新建水分子结构。 图1 水分子构建 构建AC模型 步骤如下图所示&#xff0c;单击选择Modules中的Amorphous Call&#xff0c;Calculation&#xff1b;计算精度Quality选择 U…

python爬虫之selenium4使用(万字讲解)

文章目录 一、前言二、selenium的介绍1、优点&#xff1a;2、缺点&#xff1a; 三、selenium环境搭建1、安装python模块2、selenium4新特性3、安装驱动WebDriver驱动选择驱动安装和测试 基础操作1、属性和方法2、单个元素定位通过id定位通过class_name定位一个元素通过xpath定位…

首页HF粗排模型优化

[work rus_env]$ pwd /home/work/xx/du-rus/offline-tools/du_rus/rus_env [work rus_env]$ python buildenv_rus.py 5a0e771e938a486df3b8b3e1cde1a39c2006882d 5f3241963a3e39a8e1eae05d7075fc5b9278a7c7 打开日志级别 [workxx conf]$ vim /home/work/xx/du-rus/du_rus_…

代码随想录算法训练营DAY11|C++栈和队列Part.2|LeetCode:20.有效的括号、 1047.删除字符串中所有相邻重复项、150.逆波兰表达式

文章目录 20.有效的括号思路CPP代码 1047.删除字符串中所有相邻重复项思路CPP代码 150.逆波兰表达式思路什么是逆波兰表达式本题的思路 CPP代码 20.有效的括号 力扣题目链接 文章链接&#xff1a;20.有效的括号 视频链接&#xff1a;LeetCode&#xff1a;20. 有效的括号 状态&a…

Github profile Readme实现小游戏[github自述游戏]

Github profile Readme常用于个人主页介绍&#xff0c;将它与action自动化流程结合&#xff0c;可以实现一些小游戏 例如&#xff1a;2048、五子棋 2048实现 losehu (RUBO) GitHub 五子棋 https://github.com/losehu/losehu/tree/main 通过python/C编写可执行文件&#xf…

搜索与图论——Prim算法求最小生成树

在最小生成树问题里&#xff0c;正边和负边都没问题 朴素版prim算法 时间复杂度O(n^2) 生成树&#xff1a;每一次选中的t点&#xff0c;它和集合的距离对应的那条边&#xff0c;就是生成树的一条边 算法流程和dijkstra算法非常相似 #include<iostream> #include<cs…

浏览器工作原理与实践--栈空间和堆空间:数据是如何存储的

对于前端开发者来说&#xff0c;JavaScript的内存机制是一个不被经常提及的概念 &#xff0c;因此很容易被忽视。特别是一些非计算机专业的同学&#xff0c;对内存机制可能没有非常清晰的认识&#xff0c;甚至有些同学根本就不知道JavaScript的内存机制是什么。 但是如果你想成…

039—pandas 不规则表头转换为规整DataFrame

使用步骤 读入数据 代码如下&#xff08;示例&#xff09;&#xff1a; import pandas as pd import numpy as np df pd.DataFrame({0: [姓名, 性别],1: [张三, 男],2: [年龄,np.nan],3: [18,np.nan]}) dfdf.values.reshape([4,2])r len(df.columns)(pd.DataFrame(df.valu…