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

做题步骤:

  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.mzph.cn/news/699113.shtml

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

相关文章

留子厨房开发日志

以下记录了使用go语言框架Beego&#xff0c;Mysql数据库&#xff0c;Redis数据库实现一个点菜/菜谱应用API的全过程。 技术方案 github地址 数据库设计 新建数据库&#xff1a; CREATE DATABASE menu;新建数据表&#xff1a; CREATE TABLE menu ( id int(10) unsigned NOT …

2024 CKS 题库 | 11、AppArmor

不等更新题库 CKS 题库 11、AppArmor Context: APPArmor 已在 cluster 的工作节点node02上被启用。一个 APPArmor 配置文件已存在&#xff0c;但尚未被实施。 Task: 在 cluster 的工作节点node02上&#xff0c;实施位于 /etc/apparmor.d/nginx_apparmor 的现有APPArmor 配置…

Python 实现 ADTM 指标计算:股票技术分析的利器系列(9)

Python 实现 ADTM 指标计算&#xff1a;股票技术分析的利器系列&#xff08;9&#xff09; 介绍算法解释 核心代码rolling函数介绍计算 DTMnp.where 使用介绍np.maximum 计算 DBM计算 STM计算 SBM计算 ADTM 完整代码 介绍 ADTM&#xff08;动态买卖气指标&#xff09;是一种用…

C++奇怪的 ::template

答疑解惑 怎么会有::template的写法 起初 在阅读stl的源码的时候&#xff0c;发现了一条诡异的代码 // ALIAS TEMPLATE _Rebind_alloc_t template<class _Alloc,class _Value_type> using _Rebind_alloc_t typename allocator_traits<_Alloc>::template rebind…

【misc | CTF】攻防世界 simple_transfer

天命&#xff1a;这题其实不简单啊 拿到流量包&#xff0c;丢进去wireshare&#xff0c;题目都说了flag在里面 ctrl f 直接搜索字符串 右键&#xff0c;追踪流 -> TCP流 查找 .pdf 文件&#xff0c;其实这里思路是比较奇怪的&#xff0c;毕竟是的确比较多内容&#xff0c…

基于PostGIS的慢查询引起的空间索引提升实践

目录 前言 一、问题定位 1、前端接口定位 2、后台应用定位 3、找到问题所在 二、空间索引优化 1、数据库查询 2、创建空间索引 3、geography索引 4、再看前端响应 总结 前言 这是一个真实的案例&#xff0c;也是一个新入门的工程师很容易忽略的点。往往在设计数据库的…

NestJS入门4:MySQL typeorm 增删改查

前文参考&#xff1a; NestJS入门1 NestJS入门2&#xff1a;创建模块 NestJS入门3&#xff1a;不同请求方式前后端写法 1. 安装数据库相关模块 npm install nestjs/typeorm typeorm mysql -S 2. MySql中创建数据库 ​ 3. 添加连接数据库代码 app.module.ts ​ import { M…

给自己留个备忘,blender是右手坐标系

所谓右手坐标系&#xff0c;就是三个轴的方向和右手三根手指的方向一致&#xff08;当然&#xff0c;有要求的&#xff0c;这个要求是大拇指指向x轴方向&#xff0c;食指指向y轴方向,中指指向z轴方向&#xff09;。 不过blender默认是z轴朝上的&#xff0c;如下图。 右手坐标系…

element导航菜单el-menu添加搜索功能

element导航菜单-侧栏&#xff0c;自带的功能没有搜索或者模糊查询。 找了找资料 找到一个比较可行的&#xff0c;记录一下&#xff1a; //index.vue的代码 <div style"overflow:auto"><el-menu :default-active"$route.path":default-openeds&…

<网络安全>《49 网络攻防专业课<第十三课 - 华为防火墙的使用(2)>

6 防火墙的防范技术 6.1 ARP攻击防范 攻击介绍 攻击者通过发送大量伪造的ARP请求、应答报文攻击网络设备&#xff0c;主要有ARP缓冲区溢出攻击和ARP拒绝服务攻击两种。 ARP Flood攻击&#xff08;ARP扫描攻击&#xff09;&#xff1a;攻击者利用工具扫描本网段或者跨网段主机时…

构造器详解

定义: 是一种特殊类型的方法&#xff0c;用于创建对象时初始化对象的状态。 使用new关键字创建对象 构造器特点: 1.和类名相同 2.没有返回值 public class Person {String name;public Person() {this.name"John";}}public class Test {public static void main…

vue2+element医院安全(不良)事件报告管理系统源代码

目录 安全不良事件类型 源码技术栈 医院安全&#xff08;不良&#xff09;事件报告管理系统采用无责的、自愿的填报不良事件方式&#xff0c;有效地减轻医护人员的思想压力&#xff0c;实现以事件为主要对象&#xff0c;可以自动、及时、实际地反应医院的安全、不良、近失事件…

测试环境搭建整套大数据系统(六:搭建sqoop)

一&#xff1a;下载安装包 https://archive.apache.org/dist/sqoop/ 二&#xff1a;解压修改配置。 tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C /opt cd /opt mv sqoop-1.4.7.bin__hadoop-2.6.0/ sqoop-1.4.7修改环境变量 vi /etc/profile#SQOOP_HOME export SQOOP_…

nginx-------- 高性能的 Web服务端 (四)

一、高级配置 1 .1网页的状态页 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module&#xff0c;否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机…

【Android 性能优化:内存篇】——ExoPlayer 释放后内存没有恢复问题探索

背景 最近笔者承接项目的内存优化指标&#xff0c;在内存调研的过程中发现项目中视频播放结束后&#xff0c;内存没有恢复到播放前到水平。项目中用的 EXO 版本为2.19.1&#xff0c;并且笔者自己也写了个简单的 Demo&#xff0c;发现也是如此。虽然有一些偏门方法可以优化&…

4 buuctf解题

[CISCN 2019 初赛]Love Math1 打开题目 题目源码 <?php error_reporting(0); //听说你很喜欢数学&#xff0c;不知道你是否爱它胜过爱flag if(!isset($_GET[c])){show_source(__FILE__); }else{//例子 c20-1$content $_GET[c];if (strlen($content) > 80) {die("…

无人机的视频图传技术

在操控无人机时&#xff0c;视频图传技术显得尤为关键。通过这项技术&#xff0c;无人机的摄像头所捕捉的画面能实时回传至遥控器&#xff0c;使操作者全面掌握无人机的拍摄情况。同时&#xff0c;无人机图传技术也是衡量无人机性能的重要标准&#xff0c;它关乎飞行距离与时间…

【Vuforia+Unity】AR07-实现识别条码、二维码内容功能(Barcode Scanner)

Barcode Scanner in Unity | Vuforia Library官方教程&#xff0c;写的很详细&#xff0c;本教程主要参考对象&#xff01; 主要实现扫描生活中常见的二维码&#xff0c;然后弹出二维码链接&#xff0c;当然我们也可以再次回调自定义函数&#xff0c;弹出数字内容&#xff0c;…

编译GreatSQL with RocksDB引擎

GreatSQL里也能用上RocksDB引擎 1. 前言 RocksDB 是基于Facebook 开源的一种支持事务的、高度可压缩、高性能的MyRocks存储引擎&#xff0c;特别适用于高度压缩和大容量的数据。以下是一些关键特点&#xff1a; 高性能&#xff1a; LSM 树结构使得RocksDB在写入密集型负载下表现…

剪辑视频调色软件有哪些 剪辑视频软件哪个最好 剪辑视频怎么学 剪辑视频的方法和步骤 会声会影2024 会声会影视频制作教程

看了很多调色教程&#xff0c;背了一堆调色参数&#xff0c;可最终还是调不出理想的效果。别再怀疑自己了&#xff0c;不是你的剪辑技术不行&#xff0c;而是剪辑软件没选对。只要掌握了最基本的调色原理&#xff0c;一款适合自己的视频剪辑软件是很容易出片的。 有关剪辑视频…