算法-动态规划专题

news2024/11/20 19:21:52

文章目录

    • 前言 : 动态规划简述
    • 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.coloradmin.cn/o/1624079.html

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

相关文章

代码随想录第45天|70. 爬楼梯 (进阶)322. 零钱兑换

70. 爬楼梯 &#xff08;进阶&#xff09; 57. 爬楼梯&#xff08;第八期模拟笔试&#xff09; (kamacoder.com) 代码随想录 (programmercarl.com) 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬至多m (1 < m < n)个台阶。你有多少种不同的方法可以爬到楼顶…

企业数字化转型,“业务”先行

在当今时代&#xff0c;数字化转型已经成为企业发展的必经之路。数字化转型&#xff0c;简而言之&#xff0c;就是运用数字技术&#xff0c;对企业运营管理的各个环节进行深度改造&#xff0c;以提升企业的运营效率和市场竞争力。据有关机构研究测算&#xff0c;数字化转型可使…

【静态分析】静态分析笔记07 - 指针分析基础

参考&#xff1a; 【课程笔记】南大软件分析课程7——指针分析基础&#xff08;课时9/10&#xff09; - 简书 -------------------------------------------------------------- 1. 指针分析规则 规则&#xff1a;采用推导形式&#xff0c;横线上面是条件&#xff0c;横线下…

Linux开发板配置静态IP

1、查看网口信息&#xff0c;易知eth0无IP地址 ifconfig2、首先分配一个IP地址 sudo ifconfig eth0 192.168.5.8 up3、此时配置的IP地址只是临时的&#xff0c;当你reboot重启板子上电后&#xff0c;ip地址会消失&#xff0c;因此需要为板子配置静态ip&#xff0c;避免每次上…

说方法不如传授经验向媒体投稿你可以这样

在信息爆炸的时代,作为单位的信息宣传员,肩负着将本单位的重要资讯、活动成果、政策解读等内容有效传播至公众视野的重任。其中,向各类媒体投稿无疑是实现这一目标的重要途径。然而,传统的邮件投稿方式常常让我深感力不从心,费时费力不说,成功率低、出稿慢等问题更是让我和领导…

SQL注入简单总结

一、SQL注入是什么 SQL注入即&#xff1a;是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服…

【论文推导】基于有功阻尼的转速环PI参数整定分析

前言 在学习电机控制的路上&#xff0c;PMSM的PI电流控制是不可避免的算法之一&#xff0c;其核心在于内环电流环、外环转速环的设置&#xff0c;来保证转速可调且稳定&#xff0c;并且保证较好的动态性能。整个算法仿真在《现代永磁同步电机控制原理及matlab仿真》中已详细给出…

前端项目中使用插件prettier/jscodeshift/json-stringify-pretty-compact格式化代码或json数据

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、json代码格式化-选型二、json-stringify-pretty-compact简单试用三、prettier在前端使用四、查看prettier支持的语言和插件五、使用prettier格式化vue代码最终效果如图&#xff1a; ![在这里插入图片描述](https://im…

3.8设计模式——State 状态模式(行为型)

意图 允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。 结构 Context&#xff08;上下文&#xff09;定义客户感兴趣的接口&#xff1b;维护一个ConcreteState子类的实例&#xff0c;这个实例定义当前状态。State&#xff08;状态&#xff09;定义…

[x86] OpenBMC简介

什么是 OpenBMC&#xff1f; OpenBMC 被设计为一个完整的开源 Linux 发行版&#xff0c;可以灵活地进行定制以支持不同的 SoC 或主板。 传统的BMC由固件提供商专有构建&#xff0c;是闭源的&#xff0c;这意味着它不具有在开放平台上修改的灵活性。 另一方面&#xff0c;OpenB…

链栈的基本操作(c语言实现)

栈的概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 栈的结构 定义栈…

做抖音小店,“自然流量”和“达人带货”,选择哪个更香?

大家好&#xff0c;我是电商笨笨熊 做抖音小店&#xff0c;关于选择自然流还是达人带货&#xff0c;从推出时就一直争吵到现在&#xff1b; 有人觉得自然流不需要佣金&#xff0c;一次性带来的爆单量很大&#xff1b; 有人觉得达人带货细水长流&#xff0c;虽然需要佣金&…

Docker 网络与资源控制

一 Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根 据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默 认网关。因为在同…

2000-2022年各区县农产品产量数据

2000-2022年县域农产品产量数据 1、时间&#xff1a;2000-2022年 2、指标&#xff1a;统计年度、县域名称、所属地级市、所属省份、地区编码ID、县域代码、产品种类或名称、单位、产量、 3、来源&#xff1a;统计局、县域统计年鉴、各区县政府官网 4、范围&#xff1a;具体…

基于Linux的Ncurse库的贪吃蛇项目

贪吃蛇项目的意义 承上启下&#xff1a;从C语言基础的学习&#xff1a;数据结构链表基础、C变量、流程控制、函数、指针、结构体等。过渡到Linux系统编程&#xff1a;文件编程、进程、线程、通信、第三方等。 Linux终端图形库curses curses的名字起源于"cursor optimiz…

算法学习笔记Day8——回溯算法

本文解决几个问题&#xff1a; 回溯算法是什么&#xff1f;解决回溯算法相关的问题有什么技巧&#xff1f;回溯算法代码是否有规律可循&#xff1f; 一、介绍 1.回溯算法是什么&#xff1f; 回溯算法就是个多叉树的遍历问题&#xff0c;关键在于在前序和后序时间点做一些操作…

大学生在线考试|基于SprinBoot+vue的在线试题库系统系统(源码+数据库+文档)

大学生在线考试目录 基于SprinBootvue的在线试题库系统系统 一、前言 二、系统设计 三、系统功能设计 试卷管理 试题管理 考试管理 错题本 考试记录 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#…

wps屏幕录制怎么用?分享使用方法!

数字化时代&#xff0c;屏幕录制已成为我们学习、工作和娱乐中不可或缺的一部分。无论是制作教学视频、分享游戏过程&#xff0c;还是录制网络会议&#xff0c;屏幕录制都能帮助我们轻松实现。WPS作为一款功能强大的办公软件&#xff0c;其屏幕录制功能也备受用户青睐。本文将详…

【LLM多模态】Qwen-VL模型结构和训练流程

note 观点&#xff1a;现有很多多模态大模型是基于预训练&#xff08;和SFT对齐&#xff09;的语言模型&#xff0c;将视觉特征token化并对齐到语言空间中&#xff0c;利用语言模型得到多模态LLM的输出。如何设计更好的图像tokenizer以及定位语言模型在多模态LLM中的作用很重要…

LeetCode54. 螺旋矩阵

LeetCode54.螺旋矩阵 题解思路 代码 class Solution { public:vector<int> spiralOrder(vector<vector<int>>& matrix) {vector<int> res;int n matrix.size();// 行int m matrix[0].size(); // 列vector<vector<bool>> st(n, v…