动态规划算法学习(基础)

news2024/10/7 12:25:39

做题步骤:

  1. 确定dp数组的含义(一维或者二维)

  2. 获取递推公式

  3. dp数组如何初始化

  4. 确定遍历顺序

  5. 打印dp数组(检查)

题目:

1. 斐波那契数 509

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

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

给定 n ,请计算 F(n)

解析:

  • dp数组为存放斐波那契数的容器,下标 i 代表存储斐波那契数值n的位置。

  • 递推公式:

    dp[i] = dp[i - 1] + dp[i - 2]
  • 遍历顺序从前向后

所以解题代码如下:

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

2. 爬楼梯 70

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

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

解析:

  • dp数组为存储爬楼梯方法数的容器,即爬到第 dp[i] 阶有 i 种方法。

  • 递推公式:

    dp[i] = dp[i - 1] + dp[i - 2]
  • 由于dp[0]是无意义的,同时题目要求 1 <= n <= 45 所以我们从1开始初始化即:d[1] = 1, d[2] = 2

  • 遍历顺序从前向后

所以解题代码如下:

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

3. 使用最小花费爬楼梯 746

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

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

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

解析:

  • dp数组为存储该层向上跳跃所花费能量的容器。i 表示层数。

  • 递推公式:

    • 由于到达 i 层存在两种方式

    • 通过 i - 1跳一步,花费能量:

      dp[i] = dp[i - 1] + cost[i - 1];
    • 通过 i - 2 跳两步,花费能量:

      dp[i] = dp[i - 2] + cost[i - 2];
    • 所以综上所述我们的递推公式为:

      dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
  • 接下来初始化由于题目给出我们可以在0或1位置起跳,所以

    dp[0] = dp[1] = 0
  • 遍历顺序为从前向后

所以解题代码如下:

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

4. 不同路径 62

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

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

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

解析:

  • dp数组表示一个存储到达当前位置的路径方法数目的容器。

  • 递推公式:

    • 比如我们的dp[i][j]是 C 这个位置的路径数目,我们到达 A 的路径数目有 dp[i - 1][j] 种,我们到达 B 的路径数目有 dp[i][j - 1] 种。由于机器人只能向左或者向右行走,所以我们的只能从 A 或者 B 到达 C 。所以 C 处路径总数为 A 处路径总数加上 B 处路径总数。

    • 公式为:

      dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
  • 初始化由于我们在出发点,到 x = 0 与 y = 0 位置的路径数都为1,即:

    所以初始化 x = 0, 与 y = 0 即可:

    for(int j = 0; j < n; j++) dp[0][j] = 1;
    for(int i = 0; i < m; i++) dp[i][0] = 1;
  • 遍历方向为从上到下和从左往右

所以解题代码如下:

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for(int j = 0; j < n; j++) dp[0][j] = 1;
        for(int i = 0; i < m; i++) dp[i][0] = 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];
    }
}

5. 不同路径2 63

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

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

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

网格中的障碍物和空位置分别用 10 来表示。

解析:

该题和上一题类似,递推公式一致,只需要额外增加以下两点:

  1. 递推公式需先判断该位置是否为0(无阻塞)

  2. 初始化时,如若在 x = 0 或 y = 0 位置遇到阻碍则阻碍之后的dp数组初始化定义为 0 (或null):

所以解题代码如下:

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for(int j = 0; j < n; j++) dp[0][j] = 1;
        for(int i = 0; i < m; i++) dp[i][0] = 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];
    }
}

6. 整数拆分 343

给定一个正整数 n ,将其拆分为 k正整数 的和( k >= 2 ),并使这些整数的乘积最大化。

返回 你可以获得的最大乘积

解析:

  • dp数组含义:i表示正整数值, dp[i]表示乘积最大值。

  • 递归公式:

    • 由于dp[i] = j * (i - j) => dp[i] = j * dp[i - j] (即在原有基础上在进行一次拆分);

    • 由于我们去最大值,所以为

      Math.max(Math.max(j * (i - j), j * dp[i-j]), dp[i])

      注解:为什么要再一次比较 dp[i] 呢?

      答:由于我们在遍历时,每次 j++ , dp[i]都保存上一次的最大值,所以我们需要比较当前最大值和历史最大值,取其中大的为返回值。

  • 初始化 dp[0] = 0, dp[1] = 0, dp[2] = 1;

  • 遍历方向:从左至右

所以解题代码如下:

class Solution {
    public int integerBreak(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 0;
        dp[1] = 0;
        dp[2] = 1;
        for(int i = 3; i <= n; i++){
            for(int j = 1; j <= i - j; j++){
                dp[i] = Math.max(Math.max(j * (i - j), j * dp[i-j]), dp[i]);
            }
        }
        return dp[n];
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】类和对象---友元,内部类,匿名对象详解

目录 友元 友元函数 友元类 内部类 匿名对象 ⭐友元 友元提供了一种突破封装的方式&#xff0c;有时提供了便利。但是友元会增加耦合度&#xff0c;破坏了封装&#xff0c;所以 友元不宜多用。 友元分为&#xff1a;友元函数和友元类。 ⚡友元函数 先看一个问题&#x…

React18源码: Fiber树中的全局状态与双缓冲

Fiber树构造 在React运行时中&#xff0c;fiber树构造位于 react-reconciler 包在正式解读 fiber 树构造之前&#xff0c;再次回顾一下renconciler的4个阶段 1.输入阶段&#xff1a;衔接react-dom包&#xff0c;承接fiber更新请求2.注册调度任务&#xff1a;与调度中心(schedu…

Nginx网络服务四-----日志、Nginx压缩和ssl

1.自定义访问日志 如果访问出错---404&#xff0c;可以去看error.log日志信息 访问日志是记录客户端即用户的具体请求内容信息&#xff0c;而在全局配置模块中的error_log是记录nginx服务器运行时的日志保存路径和记录日志的level&#xff0c;因此两者是不同的&#xff0c;而且…

机器视觉【3】非线性求解相机几何参数

线性求解相机几何参数的缺点 上一章节介绍学习了&#xff08;DLT&#xff09;线性求解相机几何参数&#xff0c;了解到线性求解法当中比较明显的缺点&#xff1a; 没有考虑到镜头畸变的影响不能引入更多的约束条件融入到DLT算法当中优化最关键的是&#xff0c;代数距离并不是…

Python入门学习——基础语法

一、Python解释器 1. Python解释器的作用是&#xff1a; 将Python代码翻译成计算机认识的O和1并提交计算机执行在解释器环境内可以一行行的执行我们输入的代码也可以使用解释器程序&#xff0c;去执行".py"代码文件 2. Python解释器程序在&#xff1a; <Python…

Jenkins详解

目录 一、Jenkins CI/CD 1、 Jenkins CI/CD 流程图 2、介绍 Jenkins 1、Jenkins概念 2、Jenkins目的 3、特性 4、产品发布流程 3、安装Jenkins 1、安装JDK 2、安装tomcat 3.安装maven 4安装jenkins 5.启动tomcat&#xff0c;并页面访问 5.添加节点 一、Jenkins CI/…

【Docker】免费使用的腾讯云容器镜像服务

需要云服务器等云产品来学习Linux可以移步/-->腾讯云<--/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;新用户首次下单享超低折扣。 目录 1、设置密码 2、登录实例&#xff08;sudo docker login xxxxxx&#xff09; 3、新建命名空间&#xff08;每个命名空…

【Delphi 基础知识 35】MainMenu控件的详细使用

把TmenuMain放在Form后&#xff0c;右击控件就可以对菜单进行设计 菜单中添加分割线只需加“-”就可以添加一个分割线 级联菜单的设计 单击鼠标右键弹出菜单中选择Create Submenu菜单项 单选功能设计 要在设计的菜单项目中选择RadioItem属性为True&#xff0c;Checked属性…

使用logicflow流程图实例

一.背景 需要使用流程引擎开发项目&#xff0c;没有使用flowable、activiti这类的国外流程引擎&#xff0c;想使用国内的引擎二次开发&#xff0c;缺少单例模式的流程画图程序&#xff0c;都是vue、react、angluer的不适合&#xff0c;从网上找了antx6、logicflow、bpmn.js。感…

了解人工智能计算: 人工智能入门

回顾历史&#xff0c;各种数学仪器在人类进步的历程中发挥了重要作用。从算盘和六分仪到滑尺和计算机&#xff0c;这些工具推动贸易、助力航海&#xff0c;增强理解&#xff0c;并提高了我们的生活质量。然而&#xff0c;在科学和工业领域&#xff0c;推动我们前进的前沿且强大…

Redis 工具类 与 Redis 布隆过滤器

Redis 工具类 1. 核心依赖 <!--redis--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency><groupId>com.google.guava…

网卡本质,网络发展(局域网,广域网概念)

目录 引入 网卡的本质 网络的发展 引入 早期 局域网LAN&#xff08;Local Area Network&#xff09; 广域网WAN&#xff08;Wide Area Network&#xff09; 注意 引入 前面我们已经学习了很多关于linux系统的知识,其中文件系统和线程尤为繁杂 而网络其实也算系统的一部…

Vue监听器(上)之组合式watch

1. 定义监听器 //要监视的属性被改变时触发 watch(要监视的属性, (更改后的心值, 更改前的旧值) > {具体操作}, );//监视对象为getter的时候 //表达式内任意响应式属性被改变时触发 watch(() > return表达式, (表达式的新值, 表达式的旧值) > {具体操作} );//数组中任…

如何实现一个规则研究区域内数据的提取(matlab)

在利用经验正交分解&#xff08;EOF&#xff09;进行某一个研究区域分析时&#xff0c;我们需要将研究区域转换成N*M的矩阵&#xff0c;其中N为空间维度&#xff0c;M为时间维度&#xff0c;这意味着我们之前的数据加上时间维度是三维的&#xff0c;即&#xff08;lon,lat,rg&a…

【深入理解设计模式】原型设计模式

原型设计模式 原型设计模式&#xff08;Prototype Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许通过复制已有对象来创建新对象&#xff0c;而无需直接依赖它们的具体类。这种模式通常用于需要频繁创建相似对象的场景&#xff0c;以避免昂贵的创建操作或初始化过…

泛微e-office系统敏感信息泄露漏洞

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任 1、系统简介 泛微e-office系统是标准、易用、快速部署上线的专业协同OA软…

C++之类作用域

目录 1、全局作用域 2、类作用域 2.1、设计模式之Pimpl 2.2、单例模式的自动释放 2.2.0、检测内存泄漏的工具valgrind 2.2.1、可以使用友元形式进行设计 2.2.2、内部类加静态数据成员形式 2.2.3、atexit方式进行 2.2.4、pthread_once形式 作用域可以分为类作用域、类名…

【MIT-PHP-推荐】imi-ai 是一个 ChatGPT 开源项目

mi-ai 是一个 ChatGPT 开源项目&#xff0c;支持聊天、问答、写代码、写文章、做作业等功能。 项目架构合理&#xff0c;代码编写优雅&#xff0c;简单快速部署。前后端代码完全开源&#xff0c;不管是学习自用还是商用二开都很适合。 本项目现已支持 ChatGPT 聊天 AI 和 Emb…

PyTorch概述(五)---LINEAR

torch.nn.Linear torch.nn.Linear(in_features,out_features,biasTrue,deviceNone,dtypeNone) 对输入的数据应用一个线性变换&#xff1a; 该模块支持TensorFLoat32类型的数据&#xff1b;在某些ROCm设备上&#xff0c;使用float16类型的数据输入时&#xff0c;该模块在反向传…

电路设计(28)——交通灯控制器的multisim仿真

1.功能设定 南北、东西两道的红灯时间、绿灯时间均为24S&#xff0c;数码管显示倒计时。在绿灯的最后5S内&#xff0c;黄灯闪烁。有夜间模式&#xff1a;按下按键进入夜间模式。在夜间模式下&#xff0c;数码管显示计数最大值&#xff0c;两个方向的黄灯不停闪烁。 2.电路设计 …