算法沉淀 —— 动态规划(子序列问题(上))

ArcMap 10.7/10.8启动加载界面后闪退?可能是这个隐藏的Normal.mxt模板文件在搞鬼 本文深入分析了ArcMap 10.7/10.8启动加载界面后闪退的问题,指出Normal.mxt模板文件损坏是常见原因。提供了从定位、删除模板文件到系统级修复的完整解决方案,帮助GIS工程师快速恢复工作流程。 阅读详情

前言

几乎所有的动态规划问题大致可分为以下5个步骤,后续所有问题分析都将基于此

  • 1.、状态表示:通常状态表示分为以下两种,其中更是第一种为主。

    • 以i为结尾,dp[i] 表示什么,通常为代求问题(具体依题目而定)
    • 以i为开始,dp[i]表示什么,通常为代求问题(具体依题目而定)
  • 2、状态转移方程

    • 以上述的dp[i]意义为根据, 通过最近一步来分析和划分问题,由此来得到一个有关dp[i]的状态转移方程。
  • 3、dp表创建,初始化

    • 动态规划问题中,如果直接使用状态转移方程通常会伴随着越界访问等风险,所以一般需要初始化。而初始化最重要的两个注意事项便是:保证后续结果正确,不受初始值影响;下标的映射关系。
    • 而初始化一般分为以下两种:
      • 直接初始化开头的几个值。
      • 一维空间大小+1,下标从1开始;二维增加一行/一列。
  • 4、填dp表、填表顺序:根据状态转移方程来确定填表顺序。

  • 5、确定返回值

一、最长递增子序列

【题目链接】:300. 最长递增子序列
【题目】:

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组[0,3,1,6,2,2,7] 的子序列。

【示例】:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

【分析】:
 我们可以定义dp[i]表示以i位置为结尾的最长递增子序列。由于每一个数字均可单独构成一个递增子序列,所以我们在创建dp表时,可以将dp表中的值全部初始化为1.

状态转移方程推导:

 如果dp[i]所表示的递增子序列大于1,此时在i之前一定存在某些元素和nums[i]构成递增子序列。而这些元素我们可以用dp[j[表示(0 <= j <i),并且nums[j] < nums[i]。
 但j到底在什么位置呢?我们无从而知,需要依次遍历i前的数据。来查找符合要求的最大dp[j]。所以状态转移方程为:

for(int j = i - 1; j >= 0; j--)
{
     if(nums[i] > nums[j])
         dp[i] = max(dp[i], dp[j] + 1);
 }

【其他】:
 最后只需将dp[i]的最终值累加即可!!

【代码编写】:

class Solution {
public:
    int lengthOfLIS(vector<int>& nums) {
        int n = nums.size();
        int ret = 1;
        vector<int> dp(n, 1);
        for(int i = 1; i < n; i++)
        {
            for(int j = i - 1; j >= 0; j--)
            {
                if(nums[i] > nums[j])
                    dp[i] = max(dp[i], dp[j] + 1);
            }
            ret = max(dp[i], ret);
        }
        return ret;
    }
};

二、摆动序列

【题目链接】:376. 摆动序列
【题目】:

 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。
 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。
 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。

【分析】:
 我们可以定义dp[i]表示以i位置为结尾的最大摆动序列。但我们发现i位置的状态还可以细分为上升和下降。所以我们重新定义:

  1. f[i]表示以i位置为结尾,且最后呈 ”上升“ 趋势的最大摆动序列。
  2. g[i]表示以i位置为结尾,且最后呈 ”趋势“ 的最大摆动序列。

状态转移方程推导:

  1. f[i]:最大摆动序列的长度可能为1,也可能大于1。对于大于1的情况,由于f[i]表示最后位置是呈上升趋势的摆动序列,所以nums[i] > nums[i - 1]。此时在i-1位置一定是呈下降的,即g[i-1]。所以状态转移方程如下:

在这里插入图片描述

  1. 对于g[i]来说,同理可得状态转移方程如下:
    在这里插入图片描述

细节处理:

 不管是f表还是g表,以i位置为结尾的摆动序列的最小长度一定为1,即nums[i]本身。所以我们可以直接将f表和g表中的数据的初始值设为1。后续填表过程中,仅需考虑长度大于1的情况即可!!

【代码编写】:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int n = nums.size(), ret = 1;
        vector<int> f(n, 1), g(n, 1);
        for(int i = 1; i < n ; i++)
        {
            for(int j = i - 1; j >= 0; j--)
            {
                if(nums[i] > nums[j])
                    f[i] = max(g[j] + 1, f[i]);
                else if(nums[i] < nums[j])
                    g[i] = max(f[j] + 1, g[i]);
            }
            ret = max(ret, max(f[i], g[i]));
        }
        return ret;
    }
};

三、 最长递增子序列的个数

【题目链接】:673. 最长递增子序列的个数
【题目】:

给定一个未排序的整数数组 nums , 返回最长递增子序列的个数 。
注意 这个数列必须是 严格 递增的。

【示例】:

输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。

【分析】:

 我们先定义dp[i]表示以i位置为结尾的最长递增子序列的个数。但我们发现dp[i]表示两个状态:最长递增、个数。所以我们需要将dp[i]状态细分:

  1. 我们定义len[i]表示以i位置为结尾的最长递增子序列的长度。
  2. 定义count[i]表示以i位置为结尾的最长递增子序列的个数。

 显然len[i]、count[i]最小为1,即nums[i]本身单独构成一个递增子序列。所以我们在创建len表和count表时,我们可以将初始值设为1。
 如果最大递增子序列长度大于1时,这也意味着在i前就已经存在一个递增子序列(设该子序列以j下标为结尾)。并且满足nums[i] > nums[j],此时该递增子序列(以j下标结尾,0 <= j < i)和nums[i]构成了一个新的递增子序列。
 如果最长递增子序列大于1,此时最终结果不仅要保证nums[i] > nums[j],还需保证以j位置结尾的子序列最大(即len[j]在0 ~ i-1中最大)。所以我们需要依次遍历0 ~ i-1之间len表中的左右值!!

那count[i]的值如何更新呢?

 我们可以在求len[i]的过程中,更新count[i]的值。具体如下:

  • 如果len[i] + 1 == len[j],此时count[i] += count[j]。
  • 如果len[i] + 1 > len[j],此时len[i]和count[i]的需要重新更新。即len[i] = len[j] + 1, count[i] = count[j]
  • 如果len[i] + 1 < len[j],此时count[j]是无效次数。我们直接忽略这种情况。

细节处理:
 通过上述过程我们可以的以i位置为结尾的最大递增序列和次数。所以最终整个数组中,构成的最大递增序列的次数求解可以采用和上述类型的思想。(具体查看代码)

【代码编写】:

class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
        int n = nums.size();
        vector<int> len(n, 1), count(n, 1);
        int maxlen = 1, maxcount = 1;
        for(int i = 1; i < n; i++)
        {
            for(int j = i - 1; j >= 0; j--)
            {
                if(nums[i] > nums[j])
                {
                    if(len[j] + 1 == len[i])
                        count[i] += count[j];
                    else if(len[j] + 1 > len[i])
                        len[i] = len[j] + 1, count[i] = count[j];
                }
            }
            if(len[i] == maxlen)
                maxcount += count[i];
            else if(len[i] >maxlen)
                maxlen = len[i], maxcount = count[i]; 
        }
        return maxcount;
    }
};

四、最长数对链

【题目链接】:646. 最长数对链
【题目】:

 给你一个由 n 个数对组成的数对数组 pairs ,其中 pairs[i] = [lefti, righti] 且 lefti < righti 。
 现在,我们定义一种 跟随 关系,当且仅当 b < c 时,数对 p2 = [c, d] 才可以跟在 p1 = [a, b] 后面。我们用这种形式来构造 数对链 。
 找出并返回能够形成的 最长数对链的长度 。你不需要用到所有的数对,你可以以任何顺序选择其中的一些数对来构造。

【分析】:
 由于题目中明确表示可以任意选择数组中的数来构造数对链。所以我们可以先对数组进行排序。此时我们可以定义dp[i[表示以i位置为结尾的最长数对链。

状态转移方程推导分析:

 显然dp[i]的最小值为1,即[pair[i][0], pair[i][1]]本身构成数对链。
 如果以i位置为结尾的数对链的长度大于1,此时i位置之前一定存在数对链(下标设为j,0 <= j <i)和当前元素构成一个数对链。该情况的出现需满足pairs[i][0] > pairs[j][1]。但我们最终的结果是要得到dp[j]中的最大值。我们可以直接从后往前遍历,只要查找到第一个满足条件的dp[j]即可。(原因在于我们已经对原数组进行排序)
所以状态转移方程为:

 for(int j = i -1; j >= 0; j--)
 {
      if(pairs[i][0] > pairs[j][1])
      {
          dp[i] = max(dp[i], dp[j] + 1);
          break;
      }
  }

【代码编写】:

class Solution {
public:
    int findLongestChain(vector<vector<int>>& pairs) {
        sort(pairs.begin(), pairs.end());
        int n = pairs.size(), ret = 1;
        vector<int> dp(n, 1);
        for(int i = 1; i < n; i++)
        {
            for(int j = i -1; j >= 0; j--)
            {
                if(pairs[i][0] > pairs[j][1])
                {
                    dp[i] = max(dp[i], dp[j] + 1);
                    break;
                }
            }
            ret = max(ret, dp[i]);
        }
        return ret;
    }
};
偷懒必备:3种方法快速移植MFC界面资源(含.rc文件打不开解决方案) 本文针对MFC桌面应用开发,详细介绍了三种快速移植界面资源的实战方法:直接编辑.rc文件、利用Visual Studio“添加现有项”进行可视化挂载,以及双实例拖拽应急方案。文章重点剖析了.rc文件无法打开的常见问题,提供了通过修复rc.exe等关键文件来根治此问题的解决方案,帮助开发者高效复用资源,规避ID冲突等陷阱。 阅读详情

相关推荐

Raid5损坏两块盘

  以下为浪潮Inspur NF5460M4型号服务器故障处理过程: 设备raid5组损坏两块硬,并raid组处理离线状态,情况如图:     由于硬盘数据比较重要,面对此情况不要慌我们尽量做到安全保守的保证数据尽可能完整,以下为处理方法,(遇raid5两块盘出现问题处理方法)   以下截图均为遇相同问题的解决图案,并非现场截图。 Ctrl+H 进WebBios界面,发现两...

chen_lipeng的博客 2万+

动态规划-划分子问题

浅显的描述算法的思路。

yuanyuan87的博客 1038

Petalinux实战:3种方法调试AXI UART Lite设备(含minicom/screen/直接寄存器操作对比)

本文详细介绍了在Zynq平台上使用Petalinux调试AXI UART Lite设备的三种实用方法:用户空间工具(minicom/screen)、应用层程序(termios配置)和底层寄存器直接操作。文章对比了各方法的优缺点与适用场景,并重点解析了设备树配置、驱动加载等关键环节,帮助开发者快速定位并解决串口通信中的常见问题。

weixin_29190169的博客 432

解密动态规划:从子问题到最优解的奇妙算法

动态规划(Dynamic Programming)的核心就是将大问题分解为小问题,并通过保存子问题的解以及利用子问题之间的关系来求解全局最优解。在应用动态规划之前,我们需要进行问题分析并明确问题的输入和输出,然后定义具体的状态。问题分析是动态规划的关键一步,它能够帮助我们深入理解问题的本质,并找到问题的最优子结构和重叠子问题的特征。下面对动态规划问题分析与状态定义进行详细介绍。问题分析:问题分析阶段需要明确以下几个方面的内容:a) 问题的定义:明确问题的具体形式,包括输入和输出的定义。

m0_73731708的博客 1726

从零开始搭建企业级安全扫描平台:基于Docker的Greenbone和ClamAV部署指南

本文提供了一份基于Docker容器技术,从零开始搭建企业级安全扫描平台的实战指南。详细介绍了如何部署和集成漏洞扫描工具Greenbone与病毒扫描工具ClamAV,涵盖架构设计、Docker环境优化、容器化部署步骤以及平台集成与监控方案,帮助企业构建自动化、可扩展的安全防御核心组件。

delta的博客 751

Obsidian+llama3:终于搭建了自己的知识库

Obsidian 的 Smart Connections,超出了我原本的预期,于是结合新模型非常方便地搭建了我的个人知识库。

谢彦的技术博客 3711

【动态规划】(五)动态规划——子序列问题

整理总结动态规划中的子序列问题,其中主要包括连续与不连续的子序列、编辑问题及其回文串,关键在于dp数组的定义及其删除操作后的递推公式,回文串问题核心在于dp数组的及其遍历顺序。

weixin_46216674的博客 876

优快云余额充值前必读:这5个隐藏条款,90%的开发者都忽略了(附iOS内购避坑指南)

本文揭示了优快云余额充值中90%开发者忽略的5个隐藏条款,包括不可退款规则、iOS内购限制、账号安全责任等关键内容,特别提供了iOS内购避坑指南,帮助开发者避免资金损失和账号风险。

weixin_26765287的博客 146

动态规划——子序列问题

比如上面示例2,如果 i 位置元素是11,那么它的前面可以是1,3,7等等,无法确定它前面具体是哪一个元素。dp[i][j]:表示以 i 位置元素和 j 位置元素为结尾的最长的斐波那契子序列的长度。(其中规定i < j)。f[i]:表示以 i 位置元素为结尾的所有子序列中,最后一个位置呈现上升趋势的最长摆动序列的长度。g[i]:表示以 i 位置元素为结尾的所有子序列中,最后一个位置呈现下降趋势的最长摆动序列的长度。显然是不能的,因为它的公差是不能确定的,我们至少需要两个数才能确定公差,进而去推出其他的数。

zdlynj的博客 4842

【DeepSeek开发入门】DeepSeek API 开发初体验

在人工智能蓬勃发展的时代,DeepSeek作为一款功能强大的AI大模型,为开发者提供了丰富的接口和便捷的开发体验。本文将基于DeepSeek的几个关键接口,带你快速入门,开启DeepSeek开发的探索之旅。通过本文,你已经初步了解了DeepSeek开发中几个重要接口的使用方法,包括列出模型、对话补全和查询余额接口,以及开发过程中的常见问题及解决办法。这是你踏入DeepSeek开发领域的第一步。在后续的学习中,你可以深入研究模型的参数调优,探索不同模型在各种场景下的应用,如利用模型实现更复杂的推理对话功能。

寻道AI,探索AI无限可能! 2754

【目标跟踪】基于Kalman滤波实现无人机运动轨迹跟踪附matlab代码

1 简介 在近代控制中,需要对某一特定的运动目标进行跟踪监测,并需要对其下一时间的运动位置,运动方向,速度等信息进行预先估算,才能达到对目标的即时控制.本文简要讨论了用卡尔曼滤波算法对单个目标航迹进行预测,并借助于Matlab仿真工具,对实验的效果进行评估. 2 部分代码 clc; close all; %initial state xo=25; vox=2; %Observations **** % X-Direction Calcula

qq_59747472的博客 4731

力扣算法详解

详解动态规划解题的一般步骤

真滴不可理喻的博客 1183

Python爬虫:抓取外卖平台餐厅菜单、价格与评价数据

美团外卖:国内领先的外卖平台之一,提供餐饮外卖、超市配送等服务。饿了么:另一大主流外卖平台,覆盖广泛的餐饮品类。等:国际性的外卖平台。在本文中,我们将以美团外卖为例,展示如何抓取餐厅的菜单、价格和评价等数据。我们会使用Python的爬虫库,如Scrapy和Selenium,来解决抓取任务。本文详细介绍了如何使用Python爬虫抓取外卖平台上的餐厅菜单、价格、评价等信息。我们展示了如何使用Scrapy和Selenium抓取静态与动态网页数据,如何清洗和存储数据,并讨论了如何应对外卖平台的反爬虫机制。

2201_76125261的博客 1498

算法沉淀——动态规划之子序列问题(上)(leetcode真题剖析)

这样的动态规划算法通过遍历数组,不断更新状态,最终得到以每个位置为结尾的子序列中最长递增子序列的长度。这样的动态规划算法通过遍历数组,不断更新状态,最终得到以每个位置为结尾的子序列中最长的摆动序列长度。是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。给定一个未排序的整数数组 nums , 返回最长递增子序列的个数。个位置元素为结尾的所有「子序列」中,最长递增子序列的长度。

立志做一个高产且细节博主 1734

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

算法沉淀——动态规划之子序列问题(下)(leetcode真题剖析)

(回想一下,子序列是从原序列 arr 中派生出来的,它从 arr 中删掉任意数量的元素(也可以不删),而不改变其余元素的顺序。的正整数数组形成序列 arr ,找到 arr 中最长的斐波那契式的子序列的长度。如果一个不存在,返回 0。是指在不改变其余元素顺序的情况下,通过删除一些元素或不删除任何元素而从。数组中的子序列是从数组中删除一些元素(也可能不删除)得到的一个序列。中最长等差子序列的长度,该子序列中相邻元素之间的差等于。,并且任意两个相邻元素之差相同,则称该序列为等差序列。) 的值都相同,那么序列。

立志做一个高产且细节博主 1596

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

算法沉淀——动态规划之回文串问题(上)(leetcode真题剖析)

回文子序列和回文子串的分析方式一般都是选择这段区域的「左右端点」的字符情况来分析。因为如果一个序列是回文串的话,「去掉首尾两个元素之后依旧是回文串」,「首尾加上两个相同的元素之后也依旧是回文串」。其实这里我们可以依照第一题的解法将所有的子串都进行统计,再遍历计算每个分割位置组成的3个子串是否都符合回文子串即可。和上一题思路基本一致,但这里我们要返回字串,所以我们需要在原有算法上标记字串的开始位置和子串的长度。具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

立志做一个高产且细节博主 3092

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

算法沉淀——动态规划之两个数组的 dp(上)(leetcode真题剖析)

如果我们希望确保两条直线不相交,我们可以将问题转化为在两个整数数组中寻找最长的公共子序列。这是因为,如果两条直线不相交,它们在同一列上对应的两个元素在两个数组中的顺序关系应该保持一致。是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。题目链接:https://leetcode.cn/problems/longest-common-subsequence/以这种方法绘制线条,并返回可以绘制的最大连线数。是这两个字符串所共同拥有的子序列。

立志做一个高产且细节博主 1409

算法沉淀——动态规划之斐波那契数列模型(leetcode真题剖析)

动态规划(Dynamic Programming,简称DP)是一种通过将原问题分解为相互重叠的子问题并仅仅解决每个子问题一次,将其解存储起来,避免重复计算,从而提高效率的算法优化技术。它通常用于求解最优化问题。

立志做一个高产且细节博主 1862

浅谈最长公共子序列引发的经典动态规划问题

这篇文章通过一道经典例题:最长公共子序列,给大家讲讲动态规划,并且给出一道LeetCode周赛动态规划题作为练手并讲解,相信看完文章之后,你会对动态规划有更深的理解。

qq_41468830的博客 254

算法沉淀——记忆化搜索(leetcode真题剖析)

记忆化搜索算法(Memoization)是一种通过存储已经计算过的结果来避免重复计算的优化技术,通常应用于递归算法中。这种技术旨在提高算法的效率,减少重复计算,特别是对于具有重叠子问题的问题。

立志做一个高产且细节博主 2195

最长递增子序列(LIS)问题详解:从动态规划到贪心+二分的高效解法

最长递增子序列(Longest Increasing Subsequence,LIS)是算法设计与分析中的一个经典问题,它要求在给定序列中找到一个最长的子序列,使得其元素严格递增。其核心原理在于通过动态规划进行状态定义与转移,但标准O(n²)解法在大数据量下效率低下。为解决性能瓶颈,业界普遍采用“贪心+二分查找”的优化策略,将时间复杂度降至O(n log n),极大地提升了算法在工程实践中的可用性。这种高效算法在**蓝桥杯**等算法竞赛中尤为关键,常作为考察选手对基础算法模型深度理解与灵活应用能力的试金石。

weixin_29698641的博客 215

最长公共子序列问题:从原理到 C++ 实现的深度剖析

最长公共子序列(Longest Common Subsequence,简称 LCS ),给定两个序列(比如字符串),子序列是删除若干元素(不改变元素相对顺序)得到的新序列,要找出这两个序列长度最长的公共子序列。例如序列和,最长公共子序列可以是BCAB,长度为 4。它在文本相似度检测、基因序列对比等场景有重要应用。定义dp[i][j]表示序列X的前i个元素()和序列Y的前j个元素()的最长公共子序列长度。这样定义方便处理边界情况,当i = 0或j = 0时,子序列长度自然为 0。

2401_88353317的博客 583

蓝桥杯JAVA-17.LIS最长上升子序列模板(JAVA实现)

个人博客 www.tothefor.com 蓝桥杯复习知识点汇总 纸上得来终觉浅,绝知此事要躬行。路漫漫其修远兮,吾将上下而求索!知识是经过历史的巨人沉淀下来的,别总想着自己能够快速学会,多花点时间去看看,也许会发现些不同的东西。你能快速学会的、觉得简单的东西,对于别人来说也是一样的。人外有人,天外有天。当努力到达了一定的程度,幸运自会与你不期而遇。 目录 计算最长上升子序列的长度。 动态规划 时间复杂度:O(n*n) 数组 d[ i ] 表示前 i 个数以 A[ i ] 结尾的最长上升子序列长度。 例如:

墨水记忆 1737

算法竞赛中“游园安排”类问题的模型识别与动态规划实战

动态规划是解决最优化问题的核心算法思想,其原理在于将复杂问题分解为重叠子问题,并通过存储子问题的解来避免重复计算,从而高效地找到全局最优解。这一技术在算法竞赛和工程实践中具有极高的价值,广泛应用于资源分配、路径规划和序列决策等场景。例如,在求解最长上升子序列或背包问题时,动态规划能有效处理序列选择与约束条件下的极值问题。本文以“游园安排”这一典型竞赛题目为例,深入剖析如何将生活化场景抽象为最长上升子序列或背包模型,并详细讲解利用树状数组优化状态转移、处理严格递增条件等关键实现细节,为参赛者提供从模型识别到代

weixin_32050773的博客 319

在算法实践中沉淀成长

随着刷题量的增加,我发现很多题目看似毫无关联,实则背后蕴含着相同的算法思想。如果只是零散地做题,不进行归纳总结,很难形成解题能力的迁移。于是,我开始按题型分类刷题,比如集中一段时间攻克动态规划、深度优先搜索(DFS)、广度优先搜索(BFS)等专题。在每个专题的学习中,我会建立 “题型 - 思路 - 模板” 的知识体系。例如动态规划类题目,我总结出通用的解题步骤:先确定状态定义,再找出状态转移方程,接着明确边界条件,最后优化空间复杂度。

Z15175732610的博客 706

【基础算法】动态规划从入门到进阶:记忆化搜索、线性 DP、LIS/LCS 一网打尽

本文介绍了动态规划算法的基本概念和解题方法,重点从记忆化搜索过渡到递推形式的动态规划。主要内容包括: 动态规划的核心思想是通过存储子问题的解避免重复计算,提高效率 通过斐波那契数列示例展示了记忆化搜索和递推两种实现方式 详细讲解了动态规划五步法:状态表示、状态转移方程、初始化、填表顺序和结果确定 以下楼梯问题为例,演示了如何应用动态规划解决问题 介绍了空间优化技巧,如使用滚动变量减少内存使用 文章强调动态规划学习需要循序渐进,建议通过大量练习掌握这一重要算法思想。

遇见,获得,失去,成长,释怀,完结。我与旧事归于尽,来年依旧迎花开。 515
上一篇: 算法沉淀——动态规划篇(子数组系列问题(下))
下一篇: Linux:进程等待究竟是什么?如何解决子进程僵尸所带来的内存泄漏问题?
小白debug~
小白debug~ 新星创作者: C/C++技术领域 新星创作者: C/C++技术领域
博客等级 码龄4年 3510粉丝 128原创
评论 40
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白debug~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值