算法-动态规划专题

文章目录

    • 前言 : 动态规划简述
    • 1 . 斐波那契模型
      • 1.1 泰波那契数列
      • 1.2 最小花费爬楼梯
      • 1.3 解码方法

前言 : 动态规划简述

动态规划在当前我们的理解下,其实就是一种变相的递归,我们查看一些资料也可以知道,动态规划其实属于递归的一个分支,通过把递归问题开辟的栈帧通过一定的手段放到某一种"表"中去

动态规划标准解题流
在我们«数据结构与算法分析»中是这样描述动规的
在前一节,我们看到可以被数学上递归表示的问题也可以表示成一种递归算法,在许多情形下对朴素的穷举搜索得到显著的性能改进。
任何数学递推公式都可以直接转换成递归算法,但是基本现实是编译器常常不能正确对待退归算法,结果导致低效的程序。当怀疑很可能是这种情况时,我们必须再给编译器提供一些
分解
帮助,将递归算法重新写成非递归算法,让后者把那些子问题的答案系统地记录在一个表内。利用这种方法的一种技巧叫作动 (dynamic programming)。
1 . 创建dp表(一维/二维数组)
2 . 确定我们的状态表示
---->方法是 经验+题目要求+分解为相同的子问题
---->目前已知的经验就是 以i位置为起点…/以i位置为末尾…
3 . 推导状态转移方程(相邻位置优先)
4 . 初始化(防止数组越界,处理边界位置)
5 . 填表,注意顺序(前 --> 后 / 后 --> 前)
6 . 返回值(这个跟你的开出来的dp表空间大小有关系)

7 . 空间优化(这个不是主要的…其实能写出来就不错了)

1 . 斐波那契模型

1.1 泰波那契数列

在这里插入图片描述
关于本题的具体分析见下

public class Fibonacci {/*** 寻找第 n 个泰波那契数** @param n --> 第几个数* @return*/public int tribonacci(int n) {创建dp表int[] dp = new int[n + 1];确定状态表示 --> 就是第几个泰波那契数确定状态转移方程 --> dp[n] = dp[n - 1] + dp[n - 2] + dp[n - 3]初始化if (n == 0 || n == 1) {return n;}if (n == 2) {return 1;}dp[0] = 0;dp[1] = 1;dp[2] = 1;填表(顺序从左到右)for (int i = 3; i < n + 1; ++i) {dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];}return dp[n];}
}

关于这个比较简单的题,我们还有一点要说的,请注意,这个dp表的空间是不是开的有点浪费,其实不难看出,我们真正需要的是三个临时遍历在相互赋值迭代,其实这也就是我们的空间优化的思路…
通过滚动数组来实现空间优化
在这里插入图片描述
上图是我们的空间优化可视化…
代码实现如下

class Solution {public int tribonacci(int n) {if(n == 0 || n == 1){return n;}if(n == 2){return 1;}int a = 0;int b = 1;int c = 1;int d = 0;for(int i = 3; i <= n; ++i){d = a + b + c;a = b;b = c;c = d;}return d;}
}

1.2 最小花费爬楼梯

在这里插入图片描述

下面我们根据流程来分析一下这个题目
首先我们要明白的是那个位置是楼梯顶部…
这里的数组最后一个元素不是楼梯的顶端,最后一个元素的下一个才是

  1. 创建dp表,这里我们的dp表开n+1个大小
  2. 确定状态表示 —> dp[i] 表示到达i位置所需的最小花费
  3. 确定状态转移方程(下图可视化)
    dp[i] = min(dp[i - 2] + cost[i - 2] , dp[i - 1] + cost[i - 1])
  4. 初始化 0 和 1 位置
  5. 填表,顺序从左到右
  6. 返回值,返回dp[n]
    在这里插入图片描述
    下面是我们的代码实现
class Solution {public int minCostClimbingStairs(int[] cost) {//创建dp表int[] dp = new int[cost.length + 1];dp[0] = 0;dp[1] = 0;for(int i = 2; i < cost.length + 1; ++i){dp[i] = Math.min(dp[i - 1]+cost[i - 1],dp[i - 2]+cost[i - 2]);}return dp[cost.length];}
}

解法二其实就是从后向前遍历,题解如下

class Solution {public int minCostClimbingStairs(int[] cost) {//解法2,我们换一种dp的思路(dp[i]为从i位置为起点到终点的最小花费)int len = cost.length;//初始化就应该换成最后两个元素,然后从后往前遍历int[] dp = new int[len];dp[len - 1] = cost[len - 1];dp[len - 2] = cost[len - 2];for(int i = len - 3; i >= 0; --i){dp[i] = Math.min(dp[i + 1],dp[i + 2]) + cost[i];}return Math.min(dp[0],dp[1]);}
}

1.3 解码方法

在这里插入图片描述

本题分析如下
为什么能往动态规划上面想,其实我们每个解码都可以相互拆解,就有一种斐波那契的影子,所以很自然的向我们的动态规划上面去想

  1. 创建dp表
  2. 确定状态表示(dp[i]为解码到i位置的解码方法数目)
  3. 推导状态转移方程(见下图)
    在这里插入图片描述
  4. 初始化 0 跟 1 位置
  5. 填表,顺序从左到右
  6. 输出返回值
class Solution {public int numDecodings(String s) {char[] chars = s.toCharArray();//创建dp表int[] dp = new int[s.length()];//确定状态表示 --> 就是解码到n位置的方法总数//确定状态转移方程(这个比较复杂)//初始化if (chars[0] != '0') {dp[0] = 1;}if (s.length() == 1) {return dp[0];}if (chars[1] >= '1' && chars[1] <= '9' && dp[0] != 0) {dp[1] += 1;}if ((chars[0] - '0') * 10 + chars[1] - '0' >= 10 && (chars[0] - '0') * 10 + chars[1] - '0' <= 26) {dp[1] += 1;}for (int i = 2; i < s.length(); ++i) {if (chars[i] >= '1' && chars[i] <= '9') {dp[i] += dp[i - 1];}if ((chars[i - 1] - '0') * 10 + chars[i] - '0' >= 10 && (chars[i - 1] - '0') * 10 + chars[i] - '0' <= 26) {dp[i] += dp[i - 2];}}return dp[s.length() - 1];}
}

本节会持续更新…

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

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

相关文章

1002 - 编程求解1+2+3+...+n

题目描述 编程求解下列式子的值&#xff1a; S123 \dots nS123⋯n。 输入 输入一行&#xff0c;只有一个整数 n(1 \le n \le 1000)n(1≤n≤1000) 。 输出 输出只有一行&#xff08;这意味着末尾有一个回车符号&#xff09;&#xff0c;包括 11 个整数。 样例 输入 100 …

“亚马逊依赖”之下,傲基科技的品牌势能如何提升?

受益于出口政策红利、低人工成本、完善的供应链以及成熟的生产工艺优势&#xff0c;近年来我国家具出口行业迅速发展。 数据显示&#xff0c;我国家具出口规模1995年仅为11.06亿美元&#xff0c;至2023年增至641.96亿美元。随着出口规模持续扩大&#xff0c;相关企业积极走入公…

【OpenGL实践08】现代渲染管线在GLUT和Pygame和Qt.QOpenGLWidget上各自的实现代码

Qt.QOpenGLWidget进行现代渲染管线实验效果 一、说明 据说QOpenGLWidget是用来取代QGLWidget的继承者&#xff0c;我们试图将GLUT上的旧代码改成QOpenGLWidget&#xff0c;本以为差别不大&#xff0c;轻易搞定&#xff0c;经实践发现要付出极大努力才能完成。经多次实验发现G…

【postgresql初级使用】updatable view 可修改的视图,以及视图数据致性的控制,完全分离数据报表业务与数据的维护操作部署架构尝试

可修改的视图 ​专栏内容: postgresql使用入门基础手写数据库toadb并发编程个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 文章目录 可修改的视图概述 可修改视图介绍

编译原理实验课

本人没咋学编译原理&#xff0c;能力有限&#xff0c;写的不好轻点喷&#xff0c;大佬路过的话&#xff0c;那你就路过就好 东大编译原理实验课原题&#xff0c;22年 1. 基本题&#xff1a;简单的扫描器设计 【问题描述】 熟悉并实现一个简单的扫描器&#xff0c;设计扫描器…

Spring从零开始学使用系列(三)--依赖注入(DI)

目录 1.DI的核心概念 1.1优势 2. Spring中的DI实现 2.1 构造器注入 2.1.2 优势和缺点 2.2 设置器注入 2.2.1 如何使用设置器注入 2.2.2 示例代码 2.2.3优势和使用场景 2.3 字段注入 2.4 方法注入 2.4.1 方法注入的概念 2.4.2 找方法注入 2.4.3 Lookup 注解的作用 2…

nosql数据库 redis

一、介绍 1、redis与mysql的区别&#xff1a; Redis是一种基于键值对的内存数据库&#xff0c;数据存储在内存中&#xff0c;因此读写速度非常快。它支持多种数据结构&#xff0c;如字符串、哈希、列表等。 MySQL是一种关系型数据库&#xff0c;数据以表格的形式组织存储在磁…

【Python】使用Pandas和随机森林对鸢尾花数据集进行分类

我在鼓楼的夜色中 为你唱花香自来 在别处 沉默相遇和期待 飞机飞过 车水马龙的城市 千里之外 不离开 把所有的春天 都揉进了一个清晨 把所有停不下的言语变成秘密 关上了门 莫名的情愫啊 请问 谁来将它带走呢 只好把岁月化成歌 留在山河 &#x1f3b5; 鹿…

鸿蒙原生应用元服务-访问控制(权限)开发应用权限列表二

ohos.permission.ACCELEROMETER 允许应用读取加速度传感器的数据。 权限级别 &#xff1a;normal 授权方式 &#xff1a;system_grant ACL使能 &#xff1a;TRUE ohos.permission.GYROSCOPE 允许应用读取陀螺仪传感器的数据。 权限级别 &#xff1a;normal 授权方式 &a…

探索 Python 的动态类型系统:变量引用、不可变性及高效内存管理与垃圾回收机制的深入分析

文章目录 1. 动态类型及其内存管理解析1.1 变量与对象的引用关系1.2 对象的不可变性和内存地址的变化 2. 垃圾回收与内存优化策略2.1 动态内存分配的基础2.2 Python 的垃圾回收 Python作为一种流行的高级编程语言&#xff0c;以其代码的易读性和简洁性著称。尤其是它的动态类型…

泛私域新引擎:小程序AI智能名片S2B2C商城的分销式导购策略与案例剖析

在数字化浪潮的推动下&#xff0c;小程序AI智能名片S2B2C商城以其独特的分销式导购能力&#xff0c;逐渐在泛私域的特殊场景中占据了一席之地。这种模式不仅打破了传统线上线下的界限&#xff0c;更通过以人为核心的营销方式&#xff0c;实现了利益驱动的深度分销。 分销式导购…

Git学习笔记(四)远程仓库

根据前面几篇文章的介绍&#xff0c;在本地使用Git基本不成问题了&#xff0c;常用的基本命令和一些基本概念基本也介绍完毕了。这一张主要讲讲远程仓库的创建和使用。 概念 其实在前面第一篇文章中&#xff0c;我们就简单介绍过远程仓库&#xff0c;它其实就是一个托管在远程服…

yolo-驾驶行为监测:驾驶分心检测-抽烟打电话检测

在现代交通环境中&#xff0c;随着汽车技术的不断进步和智能驾驶辅助系统的普及&#xff0c;驾驶安全成为了公众关注的焦点之一 。 分心驾驶&#xff0c;尤其是抽烟、打电话等行为&#xff0c;是导致交通事故频发的重要因素。为了解决这一问题&#xff0c;研究人员和工程师们…

19-ESP32-S3外设IIC

ESP32-S3的IIC 引言 ESP32-S3是一款集成了Wi-Fi和蓝牙功能的低成本、多功能微控制器。在这篇博客中&#xff0c;我们将详细介绍ESP32-S3的IIC&#xff08;Inter-Integrated Circuit&#xff09;接口&#xff0c;也被称为I2C。 IIC简介 IIC是一种串行、同步、多设备、半双工…

Python中, 介绍面向对象及三大特征

面向对象(Object Oriented Programming) OOP, 是一个重要的编程范式, 它主要基于"对象"的概念, 这些对象具有属性(数据)和方法(函数) 三个特征: 封装, 继承,多态 简单来说: 封装: 隐藏内部实现细节, 只保留功能接口 继承: 类与类之间的关系 (比如说父和子的关系…

CTF网络安全大赛详情

网络安全已成为现代社会的一个关键挑战&#xff0c;随着互联网技术的飞速发展&#xff0c;从个人隐私保护到国家安全&#xff0c;网络安全的重要性日益突显。为了应对这一挑战&#xff0c;CTF&#xff08;Capture The Flag&#xff0c;中文&#xff1a;夺旗赛&#xff09;应运而…

openEuler-22.03下载、安装

一、下载 下载地址&#xff1a;openEuler下载 | 欧拉系统ISO镜像 | openEuler社区官网 下载版本&#xff1a;openEuler-22.03-LTS-x86_64-dvd.iso 二、安装 配置完后开启虚拟机 设置完后&#xff0c;重启虚拟机 设置桥接模式的网络 cd /etc/sysconfig/network-scripts/ vi if…

LeetCode 2739. 总行驶距离

题目链接https://leetcode.cn/problems/total-distance-traveled/?envTypedaily-question&envId2024-04-25 简单题&#xff0c;看代码思考一下即可理解 class Solution {public int distanceTraveled(int mainTank, int additionalTank) {int res 0;while (mainTank >…

RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决

前言 开发板型号&#xff1a; 【正点原子】 的 RK3568 开发板 使用 虚拟机 ubuntu 20.04 收到单独 编译 RK3568 u-boot 【问题】u-boot 千兆网络无法ping 通&#xff1f;Linux 下千兆网络正常&#xff0c;说明&#xff1a;开发板硬件正常 u-boot 下网络如果通了&#xff0c;…

寄存器和变量有什么区别

2024年4月25日&#xff0c;周四晚上 寄存器和变量是计算机编程和计算机硬件中两个不同的概念&#xff0c;它们在内存管理和数据存储方面有着不同的作用和特点。 寄存器&#xff1a; 硬件实现&#xff1a;寄存器是计算机处理器&#xff08;CPU&#xff09;内部的一组高速存储单…