【动态规划篇】斐波那契数列拆分词句三角矩阵

news2024/12/27 13:44:38

🌠作者:@阿亮joy.
🎆专栏:《数据结构与算法要啸着学》
🎇座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
在这里插入图片描述


目录

    • 👉什么是动态规划👈
    • 👉斐波那契数列👈
    • 👉拆分词句👈
    • 👉三角矩阵👈
    • 👉总结👈

👉什么是动态规划👈

动态规划(Dynamic Programming,简称为 DP)是分治思想的延伸,通俗来说就是大事化小,小事化了的艺术。在将大问题化解为小问题的分治过程中,保存对这些小问题已经处理好的结果,并供后面处理更大规模的问题时直接使用这些结果。

动态规划具备了以下三个特点:

  • 把原来的问题分解成了几个相似的子问题
  • 所有的子问题都只需要解决一次
  • 储存子问题的解

动态规划的本质,是对问题状态的定义和状态转移方程的定义(状态以及状态之间的递推关系),动态规划问题一般从以下四个角度来考虑:状态定义、状态间的转移方程定义、状态的初始化和返回结果。

状态定义的要求:定义的状态一定能够形成递推关系。动态规划适用的场景:最大最小值问题、可不可行、是不是以及方案个数等问题。

👉斐波那契数列👈

这里是引用

斐波那契数列不管是递归版本和循环版本的解法,都是非常简单的,但是它仍然是非常经典的一道动态规划的题目。它能够让我们很好去熟悉动态规划状态的定义、状态转移方程的定义、状态的初始化以及返回结果。

状态:F(i) 第 i 项斐波那契数
状态转移方程:F(i) = F(i - 1) + F(i - 2)
初始状态:F(0) = 0,F(1) = 1,F(2) = 1
返回结果:F(n) 第 n 项斐波那契数

以上的分析过程是非常重要的,特别是对一些难题,这也是解决动态规划题目的难点所在。

class Solution 
{
public:
    int Fibonacci(int n) 
    {
        // 创建数组,保存中间状态的解
        int* F = new int[n + 1];
        // 初始化F(0)和F(1)
        F[0] = 0, F[1] = 1;
        // 状态转移方程F(i) = F(i-1) + F(i-2)
        for(int i = 2; i <= n; ++i)
        {
            F[i] = F[i - 1] + F[i - 2];
        }
        // 返回结果
        int ret = F[n];
        delete[] F;
        return ret;
    }
};

其实我们求解当前第 i 项的斐波那契数,只需要前两项的斐波那契数,所以我们可以对空间复杂度进行进一步的优化。

class Solution 
{
public:
    int Fibonacci(int n) 
    {
        int f0 = 0;
        int f1 = 1;
        int fn = 1;
        for(int i = 2; i <= n; ++i)
        {
            // f0为F(i-2),f1为F(i-1)
            fn = f0 + f1;
            f0 = f1;
            f1 = fn;
        }
        return fn;
    }
};

👉拆分词句👈

给定一个字符串s和一组单词dict,判断s是否可以用空格分割成一个单词序列,使得单词序列中所有的单词都是dict中的单词(序列可以包含一个或多个单词)。例如:
给定s=“nowcode”;dict=[“now”, “code”]。返回true,因为"nowcode"可以被分割成"now code"。

如果我们想一下采用暴力的方式去分割字符串的话,很明显是行不通的。这时候,我们可以尝试一下采用动规。动态最难的就是如何定义状态以及状态定义好后,如何确定状态转移方程。完成了这两部,题目也差不多可以解决了。

那状态(子问题)如何确定呢?其实状态一般都是从问题中抽象出来的。本道题的问题是字符串 s 是否可以被分割,那么状态 F(i) 是不是就是字符串 s 的前 i 个字符是否可以被分割。那接下来就确定状态转移方程,见下图。

在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

class Solution 
{
public:
    bool wordBreak(string s, unordered_set<string> &dict) 
    {
        if(dict.empty())	// 词典为空
        {
            return false;
        }
        
        vector<bool> canBreak(s.size() + 1, false);
        // 初始状态
        canBreak[0] = true;

        for(int i = 1; i <= s.size(); ++i)
        {
            // j < i && F(j) && 第[j + 1, i]字符组成的单词是否在词典里
            for(int j = 0; j < i; ++j)
            {
                
                if(canBreak[j] && (dict.find(s.substr(j, i - j)) != dict.end()))
                {
                    canBreak[i] = true;
                    break;
                }
            }
        }

        return canBreak[s.size()];
    }
};

通过拆分词句这道题,我们也可以看出状态方程不一定是一个等式,且需要辅助状态(实际不存在的状态)。

👉三角矩阵👈

这里是引用

思路一:从上向下推
在这里插入图片描述

class Solution 
{
public:
    int minimumTotal(vector<vector<int> > &triangle) 
    {
        if(triangle.empty())
        {
            return 0;
        }

        int row = triangle.size();
        int col = triangle[0].size();
        for(int i = 1; i < row; ++i)
        {
            for(int j = 0; j <= i; ++j)
            {
                if(j == 0)
                {
                    triangle[i][j] += triangle[i - 1][j];
                }
                else if(j == i)
                {
                    triangle[i][j] += triangle[i - 1][j - 1];
                }
                else
                {
                    triangle[i][j] += min(triangle[i - 1][j - 1], triangle[i - 1][j]);
                }
            }
        }
		// 找出从顶部到底部的最小路径和
        int ret = triangle[row - 1][0];
        for(int j = 1; j < row; ++j)
        {
            if(triangle[row - 1][j] < ret)
            {
                ret = triangle[row - 1][j];
            }
        }

        return ret;
    }
};

思路二:从下向上推

在这里插入图片描述

class Solution 
{
public:
    int minimumTotal(vector<vector<int> > &triangle) 
    {
        if(triangle.empty())
        {
            return 0;
        }

        int row = triangle.size();
        int col = triangle[0].size();
        for(int i = row - 2; i >= 0; --i)
        {
            for(int j = 0; j <= i; ++j)
            {
                triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1]);
            }
        }

        return triangle[0][0];
    }
};

通过这道题目可以看出,状态定义的不同,状态转移方程也会不同,代码量和简洁程度也会有所不同。

👉总结👈

本篇博客主要讲解了什么是动态规划以及几道动态规划的题目:斐波那契数列、拆分词句和三角矩阵。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️

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

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

相关文章

基于Java(JSP+Servlet)+Mysql实现的(Web)简易的工资管理系统【100010062】

1.问题描述 一个公司下分为若干部门&#xff0c;每个部门有若干职员和经理&#xff0c;每个部门经销若干种商品。工资由基本工资、产品销售业绩奖、若干种保险的扣除等组成。其中的销售业绩奖按以下方式设计&#xff1a;职员按其完成额的 5% 提成&#xff0c;经理按其部门完成…

string.IsNullOrEmpty和string.IsNullOrWhiteSpace的区别

string.IsNullOrEmpty和string.IsNullOrWhiteSpace 本人一直使用的是string.IsNullOrEmpty方法来判断字符串是否为空. 在插件中发现另外一种写法&#xff1a; string s1 null; string s2 string.Empty; string s3 ""; strin…

精通MyBatis原理,看这两篇就够了!(二)

本文是关于MyBatis源码的第二篇&#xff0c;解读了MyBatis的核心执行SQL流程&#xff0c;对源码做了详细注释。内容较长&#xff0c;推荐电脑阅读。点击上方“后端开发技术”&#xff0c;选择“设为星标” &#xff0c;优质资源及时送达执行阶段流程第一篇文章讲解了Mybatis启动…

【jdk11+jprofiler 11进行java程序性能调优案例之--内存溢出原因分析】

1.安装jprofiler jprofiler_windows-x64_11_0_2.exe 2.使用KeyGen.exe生成注册码然后输入 3.idea中安装jprofiler插件 File-->Setting-->Plugins 搜索jprofiler插件然后安装 4.以一个内存溢出的程序为例子进行分析(一直分配内存&#xff0c;List容器引用着Student导致…

Java创建线程的三种方式

Java创建线程的三种方式 一、通过Thread类的方式进行创建 步骤&#xff1a; 1、创建Thread的子类&#xff0c;重写run方法&#xff0c;run方法就表示线程需要完成的任务 2、创建Thread实例&#xff0c;也就是创建线程对象 3、使用start来启动线程&#xff08;线程启动的唯一方…

显著性分析

选择图 为什么要分Non-parametric & parametric 方法 为了找到更符合数据的分析方法。每个方法有自己的假设&#xff0c;如果违背了结果会不精准。 Sign Test 是一个可以用于任何数据分布情况的pairwise 方法。 检查normality: Sample 数量 < 50,适用 Shapiro-Wilk&am…

【Kotlin 协程】Flow 操作符 ① ( 过渡操作符 | map 操作符 | transform 操作符 | 限长操作符 | take 操作符 )

文章目录一、过渡操作符1、map 操作符2、transform 操作符二、限长操作符 ( take 操作符 )一、过渡操作符 过渡操作符 相关概念 : 转换流 : 使用 过渡操作符 转换 Flow 流 ;作用位置 : 过渡操作符作用 于 流的上游 , 返回 流的下游 ;非挂起函数 : 过渡操作符 不是挂起函数 , 属…

大话JMeter2|正确get参数传递和HTTP如何正确使用

上节课展示了JMeter的基础用法&#xff1a;录制回放功能&#xff0c;断言&#xff0c;聚合报告。但是在无UI下如何进行接口的访问呢&#xff1f;如何正确get参数传递和HTTP如何正确使用。尤其是在无UI下进行接口的访问。小哥哥带着你用漫画来学习JMeter&#xff0c;让你在轻松的…

【MMAsia 2021】Patch-Based Deep Autoencoder for Point Cloud Geometry Compression

文章目录Patch-Based Deep Autoencoder for Point Cloud Geometry Compression压缩流程自编码架构实验结果Patch-Based Deep Autoencoder for Point Cloud Geometry Compression https://arxiv.org/abs/2110.09109 这篇论文使用深度自编码器&#xff0c;提出了一种基于分块&am…

发票识别OCR及查验API接口为企业化解难题

对于当今的现代企业来说&#xff0c;分散的财务管理模式效率不高&#xff0c;管理成本反而相对较高&#xff0c;制约了集团企业发展战略的实施&#xff0c;因而需要建设财务共享模式。一个企业要建成财务共享中心&#xff0c;面临的难题是大量的数据采集和信息处理工作&#xf…

一组类型相同的数据【C 数组】总结

作者 &#xff1a; 会敲代码的Steve 墓志铭&#xff1a;博学笃志 切问静思 前言&#xff1a;本文旨在复习C语言数组章节的知识点、分为以下几个部分&#xff1a; 什么是数组一维数组、一维数组的初始化、一维数组的遍历、冒泡排序。二维数组、二维数组的创建和初始化、二维数…

多功能采集仪VH03接口使用说明

传感器接口 传感器接口须使用设备专门配备的测线&#xff0c;一端为 DB9 一端为用颜色区分的多个鳄鱼夹&#xff0c;线&#xff08;鳄鱼夹&#xff09;颜色和功能定义详见“设备组成和接口定义” 。 充电和通讯接口 VH03 使用标准的 USB Type-C 接口完成设备充电和通讯&…

创建一个vue项目

文章目录前言一、安装node.js二、vue ui命令没有反应原因1.vue ui命令是vue 3.x版本以上才支持&#xff0c;因此需要更新vue的版本。2.更新vue版本2.1首先使用以下命令卸载旧版本2.2然后使用下面命令安装最新版本2.3查看是当前版本号2.4此时&#xff0c;输入 vue -h 命令查看co…

HMS Core 3D流体仿真技术,打造移动端PC级流体动效

移动设备硬件的高速发展&#xff0c;让游戏行业发生翻天覆地的变化&#xff0c;许多酷炫的游戏效果不再局限于电脑端&#xff0c;玩家在移动端就能享受到场景更逼真、画质更清晰、体验更流畅的游戏服务。但由于移动设备算力不足&#xff0c;为了实现真实感的水体效果&#xff0…

cesium地形上面绘点时,山背面点位始终显示在地形上

cesium地形上面绘点时&#xff0c;山背面点位始终显示在地形上&#xff0c;如下图&#xff1a; 深度检测也是打开的&#xff0c;各种方法试完之后&#xff0c;也没有找到问题&#xff0c;把viewer属性注释之后&#xff0c;就没有出现这个问题&#xff0c;于是一个个属性&#…

【LeetCode】C语言实现---用队列实现栈用栈实现队列

目录&#x1f449;用队列实现栈&#x1f449;用栈实现队列&#x1f449;用队列实现栈 入口&#xff1a;OJ 题目描述&#xff1a; 请你仅使用两个队列实现一个后入先出&#xff08;LIFO&#xff09;的栈&#xff0c;并支持普通栈的全部四种操作&#xff08;push、top、pop 和 em…

redis的消息发布订阅实现

文章目录前言一、创建好springboot项目,引入核心依赖二、使用步骤1. 自定义一个消息接受类2.声名一个消息配置类3.编写一个测试类总结前言 一般项目中都会使用redis作为缓存使用,加速用户体验,实现分布式锁等等,redis可以说为项目中的优化,关键技术实现立下了汗马功劳.今天带来…

YonBuilder应用构建教程之移动端基础配置

在YonBuilder中除了PC端应用的构建外&#xff0c;我们还可以构建配套的移动端页面。对于同一个数据实体可以实现PC端和移动端的数据同步修改&#xff0c;使数据录入、修改、审批等更加便捷。本篇文章通过对员工信息实体的移动端页面构建来对YonBuilder移动端配置的基础流程进行…

利用ENVI对遥感图像校正

1.几何校正 引起图像几何变形一般分为两大类:系统性和非系统性。系统性一般由传感器本身引起&#xff0c;有规律可循和可预测性&#xff0c;可以用传感器模型来校正&#xff0c;卫星地面接收站已经完成这项工作;非系统性几何变形是不规律的&#xff0c;它可以是传感器平台本身…

【Axure高保真原型】移动端钱包原型模板

今天和大家分享移动端钱包的原型模板&#xff0c;里面包含了11大模块&#xff0c;各个模块都是高保真高交互的原型模板&#xff0c;大家可以在演示地址里体验哦 【原型预览及下载地址】 https://axhub.im/ax9/4c3757a85d201a4c/#c1 这个原型还可以在手机上演示哦&#xff0c…