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

做题步骤:

  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];
    }
}

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

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

相关文章

Axtue使用笔记

1、有三种方式可以设置元件顺序 第一种是鼠标右键点击顺序&#xff0c;选择调整操作置顶、置底、上移一层、下移一层&#xff1b; 第二种是在顶部工具栏中&#xff0c;选择调整操作置顶、置底、上移一层、下移一层; 第三种是使用快捷键操作 Windows&#xff1a;置顶&#xff1a…

Java Web(八)--Servlet(一)

介绍 官网&#xff1a;Servlet 3.1 API Documentation - Apache Tomcat 8.0.53 为什么需要&#xff1f; 提出需求: 请用你现有的html css javascript&#xff0c;开发网站&#xff0c;比如可以让用户留言/购物/支付? 引入我们动态网页(能和用户交互)技术>Servlet 是什…

Linux权限的理解

一、Linux权限的概念 1.1Linux的两种用户 Linux下有两种用户&#xff1a;超级用户(root)和普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的命令提示符是“#”&#xff0c;普通用户的…

深入了解Java泛型的底层原理

深入了解Java泛型的底层原理 在Java编程中&#xff0c;泛型是一项强大的特性&#xff0c;它允许我们编写更加通用和类型安全的代码。然而&#xff0c;对于许多开发者来说&#xff0c;泛型的底层原理可能并不清晰。本文将深入探讨Java泛型的底层实现原理&#xff0c;帮助您更好…

深入探索Linux:ACL权限、特殊位与隐藏属性的奥秘

前言&#xff1a; 在Linux系统中&#xff0c;文件和目录的权限管理是一项至关重要的任务。它决定了哪些用户或用户组可以对文件或目录执行读、写或执行等操作。传统的Linux权限模型基于用户、组和其他的概念&#xff0c;但随着时间的推移&#xff0c;这种模型在某些情况下显得…

Bean的声明周期

1.创建Bean对象&#xff08;调用无参数构造&#xff09; 2.给bean对象设置相关属性&#xff08;依赖注入&#xff09; 3.bean后置处理器&#xff08;初始化前执行&#xff0c;类似于过滤器和拦截器&#xff09; 首先要定义一个类MyBeanPost&#xff0c;实现BeanPostProcessor…

解锁业务灵活性:RuleGo规则引擎的高效解耦与实时响应秘籍

文章目录 入门指南&#xff1a;RuleGo规则引擎&#x1f389; 概述&#x1f3c6; RuleGo的优势&#x1f680; 特性&#x1fa81; 架构图使用场景&#x1f3af; 典型使用场景规则链概述RuleGo规则链优势规则链配置示例 入门指南&#xff1a;RuleGo规则引擎 &#x1f389; 概述 …

嵌入式中十大经典排序算法(代码实现),建议收藏

前言 兜兜转转&#xff0c;时间如白驹过隙。时间证明了一个道理&#xff0c;学啥忘啥&#xff0c;学的越快忘得越快&#xff0c;还不如踏踏实实写点笔记心得来的实在。 编程初学期间&#xff0c;排序算法是让人抓头最多的一块。为什么我连最简单的冒泡排序都理解不了&#xff…

【动态规划】【状态压缩】LCP04 覆盖

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 本文涉及知识点 动态规划汇总 LCP04 覆盖 你有一块棋盘&#xff0c;棋盘上有一些格子已经坏掉了。你还有无穷块大小为1 * 2的多米诺骨牌&#xff0c;你想把这些骨牌不重叠地覆盖在完好的格子上&#xff0…

C#学习总结

1、访问权限 方法默认访问修饰符&#xff1a;private 类默认访问修饰符&#xff1a;internal 类的成员默认访问修饰符&#xff1a;private 2、UserControl的使用 首先添加用户控件 使用时一种是通过代码添加&#xff0c;一种是通过拖动组件到xaml中

音频的“隐形保镖”——音频数字水印

在互联网时代&#xff0c;多媒体数字资源可以快捷地传播和获取&#xff0c;但同时也导致了数字音频产品的非法扩散、非法拷贝和非法篡改猖獗&#xff0c;数字音频产品的完整性和版权保护问题越来越凸显。文档和图像可以添加水印&#xff0c;音频同样可以添加水印&#xff0c;让…

【递归版】归并排序算法(1)

目录 MergeSort归并排序 整体思想 图解分析 代码实现 时间复杂度 递归&归并排序VS快速排序 MergeSort归并排序 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法&#xff08;Divide and Conquer&a…

堆排序法的名字由来,排序步骤是什么,最坏情况下的排序次数如何计算得来的呢?

问题描述&#xff1a;堆排序法的名字由来&#xff0c;排序步骤是什么&#xff0c;最坏情况下的排序次数如何计算得来的呢&#xff1f; 问题解答&#xff1a; 堆排序法的名字来源于它使用了堆这种数据结构。堆是一种特殊的树形数据结构&#xff0c;具有以下特点&#xff1a;在…

基于RK3399 Android11适配OV13850 MIPI摄像头

目录 1、原理图分析2、编写和配置设备树3、调试方法4、遇到的问题与解决5、补丁 1、原理图分析 从上图可看出&#xff0c;我们需要关心的&#xff0c;①MIPI数据和时钟接口使用的是MIPI_TX1/RX1 ②I2C使用的是I2C4总线 ③RST复位引脚使用的是GPIO2_D2 ④PWDN使用的是GPIO1_C7 ⑤…

A星寻路算法详解

A星寻路算法 前言 A星寻路算法是静态路网中求解最短路径最有效的直接搜索方法&#xff0c;也是解决许多搜索问题的有效算法&#xff0c;它可以应对包括复杂地形&#xff0c;各种尺度的障碍物以及不同地形的路径规划问题。掌握A星寻路算法能够提高路径规划效率&#xff0c;应对…

大模型参数高效微调

参数高效微调目的 PEFT技术旨在通过最小化微调参数的数量和计算复杂度&#xff0c;来提高预训练模型在新任务上的性能&#xff0c;从而缓解大型预训练模型的训练成本。这样一来&#xff0c;即使计算资源受限&#xff0c;也可以利用预训练模型的知识来迅速适应新任务&#xff0…

域名 SSL 证书信息解析 API 数据接口

域名 SSL 证书信息解析 API 数据接口 网络工具&#xff0c;提供域名 SSL 证书信息解析&#xff0c;多信息查询&#xff0c;毫秒级响应。 1. 产品功能 提供域名 SSL 证书信息解析&#xff1b;最完整 SSL 属性信息解析&#xff1b;支持多种元素信息抽取&#xff0c;包括主题的可…

【Java程序设计】【C00278】基于Springboot的数码论坛管理系统(有论文)

基于Springboot的数码论坛管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的数码论坛系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、…

Linux:Jenkins:GitLab+Maven+Jenkins的部署

1.环境 我这里准备了三台centos7 1.用于部署gitlab 运行内存&#xff1a;6G 名字&#xff1a;Jenkins-GitLab 192.168.6.1 2.用于部署jenkins 运行内存&#xff1a;2G 名字&#xff1a;Jenkins-server 192.168.6.2 3.用于打包测试…

全面解析企业财务报表系列之五:阅读财报结构、顺序、模块与不同侧重

全面解析企业财务报表系列之五&#xff1a;阅读财报结构、顺序、模块与不同侧重 一、明确本次报表分析的目的二、确定报表分析的重点项目三、重点分析项目之间的联系四、资产负债表的阅读五、利润表的阅读六、现金流量表的阅读七、综合分析 一、明确本次报表分析的目的 报表的…