当前位置: 首页 > article >正文

dfs记忆化搜索刷题 + 总结

文章目录

  • 记忆化搜索 vs 动态规划
  • 斐波那契数
    • 题解
    • 代码
  • 不同路径
    • 题解
    • 代码
  • 最长递增子序列
    • 题解
    • 代码
  • 猜数字大小II
    • 题解
    • 代码
  • 矩阵中的最长递增路径
    • 题解
    • 代码
  • 总结

记忆化搜索 vs 动态规划

1. 记忆化搜索:有完全相同的问题/数据保存起来,带有备忘录的递归
2.记忆化搜索的步骤:
1、添加一个备忘录 <可变参数,返回值>
2、递归每次返回的时候,将结果放入备忘录中
3、在每次进入递归的时候,往备忘录中查找一下

3. 记忆化搜索和常规的动态规划都是动态规划,暴搜 -> 记忆化搜索 -> 动态规划
4. 有大量重复的问题才能改成记忆化搜索

在这里插入图片描述

斐波那契数

题目链接
在这里插入图片描述

题解

1. 创建一个备忘录
2. 把备忘录中的值初始化为斐波那契数中不可能出现的的值-1
3. 在每次递归完成之前,把值存入备忘录中
4. 在每次进入递归的时候,查找一下备忘录中是否有值,有值就直接返回,相当于剪枝

代码

class Solution 
{
public:// 记忆化搜索int memo[31];int fib(int n) {memset(memo,-1,sizeof memo);return dfs(n);}int dfs(int n){if(memo[n] != -1){return memo[n];}if(n == 0 || n == 1){memo[n] = n;return n;}memo[n] = dfs(n-1) + dfs(n-2);return memo[n];}
};// 动态规划
class Solution 
{
public:int dp[31];int fib(int n) {dp[0] = 0,dp[1] = 1;for(int i = 2;i <= n;i++){dp[i] = dp[i-1] + dp[i-2];}return dp[n];}
};

不同路径

题目链接
在这里插入图片描述

题解

1. 函数头的设计,只需要i和j的坐标
2. 返回条件:i == 0 || j == 0都是返回0
i == 1 && j == 1 第一个点返回1
3. 记忆化搜索就是创建一个二维的备忘录,在递归之前往备忘录中查找一下,返回之前把结果都存在备忘录中

在这里插入图片描述

代码

// 记忆化搜索
class Solution 
{
public:int memo[102][102];int uniquePaths(int m, int n) {return dfs(m,n);}int dfs(int m,int n){// 往备忘录中查找一下if(memo[m][n]) return memo[m][n];   // 返回条件if(m == 0 || n == 0) return 0;// 第一个点if(m == 1 && n == 1){memo[m][n] = 1;return 1;} memo[m][n] = dfs(m-1,n) + dfs(m,n-1);return memo[m][n];}
};// 动态规划
class Solution 
{
public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1));dp[1][1] = 1;for(int i = 1;i <= m;i++){for(int j = 1;j <= n;j++){if(i == 1 && j == 1) continue;dp[i][j] = dp[i-1][j] + dp[i][j-1];}}    return dp[m][n];}
};

最长递增子序列

题目链接
在这里插入图片描述

题解

1. 记忆化搜索:每次枚举以pos位置为起点的最长递增子序列,让pos+1位置的值和pos位置比较大小,如果大于就加一,函数头需要nums和pos位置,函数体需要pos+1位置到n-1位置,dfs会完成找到最大递增子序列的工作,+1是加上本身
2. 动态规划:从后往前添加状态,第一个循环用来枚举位置,第二个循环用来比较大小,更新最长递增子序列到dp[i]中,内层循环结束,更新一下最长的子序列,因为不知道哪个位置是最大的

在这里插入图片描述

代码

 // 记忆化搜索
class Solution 
{
public:int memo[2510];int lengthOfLIS(vector<int>& nums) {int ret = 1;// 每次以i位置为起点往后搜索for(int i = 0;i < nums.size();i++){ret = max(dfs(nums,i),ret);}return ret;}int dfs(vector<int>& nums,int pos){if(memo[pos] != 0) return memo[pos];int ret = 1;for(int i = pos+1;i < nums.size();i++){if(nums[i] > nums[pos])ret = max(ret,dfs(nums,i)+1);}memo[pos] = ret;return memo[pos];}
};// 动态规划
class Solution 
{
public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();// 最短的子序列都是1vector<int> dp(n,1);int ret = 1;for(int i = n-1;i >= 0;i--){for(int j = i+1;j < n;j++){if(nums[j] > nums[i]){dp[i] = max(dp[i],dp[j] + 1);}}ret = max(ret,dp[i]);}    return ret;}
};

猜数字大小II

题目链接
在这里插入图片描述

题解

1. 暴搜 -> 记忆化搜索
2. 算法原理:在区间[1,n]固定一个点i,分为左右区间,寻找花费最小金钱达到必胜的方案,方案数是不止实例一那一种的,然后在左右枝中寻找所花费金额的最大值才能胜利
3. 函数头需要传参左右区间,函数体需要实现寻找多种方案中的最小花费和当前方案下的最大金钱,出现了重复的数据可以使用记忆化搜索

在这里插入图片描述

代码

class Solution 
{
public:int memo[201][201];int getMoneyAmount(int n) {// 计算出所有方案数中的最小花费return dfs(1,n);}int dfs(int left,int right){if(left >= right) return 0;if(memo[left][right] != 0) return memo[left][right];int ret = INT_MAX;for(int head = left;head <= right;head++){int x = dfs(left,head-1);int y = dfs(head+1,right);ret = min(ret,max(x,y) + head);}memo[left][right] = ret;return ret;}
};

矩阵中的最长递增路径

题目链接
在这里插入图片描述

题解

1. 算法原理:从一个点开始dfs,暴力枚举出每一个递增的路径,返回其中最长的路径即可
2. dfs函数的设计,需要i,j坐标去搜索每一个位置
3. 记忆化数组,如果出现相同的路径,不用再次dfs,直接返回即可

在这里插入图片描述

代码

class Solution 
{
public:int memo[201][201];int m,n;int longestIncreasingPath(vector<vector<int>>& matrix) {int ret = 1;m = matrix.size(),n = matrix[0].size();for(int i = 0;i < m;i++){for(int j = 0;j < n;j++){ret = max(ret,dfs(matrix,i,j));}}return ret;}int dx[4] = {-1,1,0,0};int dy[4] = {0,0,-1,1};int dfs(vector<vector<int>>& matrix,int i,int j){if(memo[i][j]) return memo[i][j];int ret = 1;for(int k = 0;k < 4;k++){int x = dx[k] + i,y = dy[k] + j;if(x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] > matrix[i][j]){ret = max(ret,dfs(matrix,x,y) + 1);}}memo[i][j] = ret;return ret;}
};

总结

1. 记忆化搜索就是先把暴力的dfs先写出来,然后加一个备忘录优化
2. 记忆化搜索也和常规的动态规划是一样的,即记忆化搜索也可以改为动态规划的代码
3. 出现大量重复的数据可以使用记忆化搜索,记忆化搜索可以使原本O(2^n)时间复杂度降为O(n)

相关文章:

dfs记忆化搜索刷题 + 总结

文章目录 记忆化搜索 vs 动态规划斐波那契数题解代码 不同路径题解代码 最长递增子序列题解代码 猜数字大小II题解代码 矩阵中的最长递增路径题解代码 总结 记忆化搜索 vs 动态规划 1. 记忆化搜索&#xff1a;有完全相同的问题/数据保存起来&#xff0c;带有备忘录的递归 2.记忆…...

vue2 全局封装axios统一管理api

在vue项目中&#xff0c;经常会使用到axios来与后台进行数据交互&#xff0c;axios丰富的api满足我们基本的需求。但是对于项目而言&#xff0c;每次都需要对异常进行捕获或者处理的话&#xff0c;代码会很繁重冗余。我们需要将其公共部分封装起来&#xff0c;比如异常处理&…...

大模型有哪些算法

大模型&#xff08;Large-scale Models&#xff09;通常指参数量大、架构复杂、在特定任务或领域表现出色的深度学习模型。这些模型的算法核心往往基于Transformer 架构及其变体&#xff0c;同时结合了大规模数据、硬件加速和优化技巧。以下是当前主流大模型及其核心算法的分类…...

【Linux】进程的详讲(中上)

目录 &#x1f4d6;1.什么是进程? &#x1f4d6;2.自己写一个进程 &#x1f4d6;3.操作系统与内存的关系 &#x1f4d6;4.PCB(操作系统对进程的管理) &#x1f4d6;5.真正进程的组成 &#x1f4d6;6.形成进程的过程 &#x1f4d6;7、Linux环境下的进程知识 7.1 task_s…...

Python Cookbook-4.17 字典的并集与交集

任务 给定两个字典&#xff0c;需要找到两个字典都包含的键(交集)&#xff0c;或者同时属于两个字典的键(并集)。 解决方案 有时&#xff0c;尤其是在Python2.3中&#xff0c;你会发现对字典的使用完全是对集合的一种具体化的体现。在这个要求中&#xff0c;只需要考虑键&am…...

优选算法的巧思之径:模拟专题

专栏&#xff1a;算法的魔法世界 个人主页&#xff1a;手握风云 目录 一、模拟 二、例题讲解 2.1. 替换所有的问号 2.2. 提莫攻击 2.3. Z字形变换 2.4. 外观数列 2.5. 数青蛙 一、模拟 模拟算法说简单点就是照葫芦画瓢&#xff0c;现在草稿纸上模拟一遍算法过程&#xf…...

【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft 服务器搭建,并实现远程联机,详细教程

【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft 服务器搭建&#xff0c;详细详细教程 一、 服务器介绍二、下载 Minecraft 服务端三、安装 JDK 21四、搭建服务器五、本地测试连接六、添加服务&#xff0c;并设置开机自启动 前言&#xff1a; 推荐使用云服务器部署&…...

文本分析(非结构化数据挖掘)——特征词选择(基于TF-IDF权值)

TF-IDF是一种用于信息检索和文本挖掘的常用加权算法&#xff0c;用于评估一个词在文档或语料库中的重要程度。它结合了词频&#xff08;TF&#xff09;和逆文档频率&#xff08;IDF&#xff09;两个指标&#xff0c;能够有效过滤掉常见词&#xff08;如“的”、“是”等&#x…...

【JavaSE】小练习 —— 图书管理系统

【JavaSE】JavaSE小练习 —— 图书管理系统 一、系统功能二、涉及的知识点三、业务逻辑四、代码实现4.1 book 包4.2 user 包4.3 Main 类4.4 完善管理员菜单和普通用户菜单4.5 接着4.4的管理员菜单和普通用户菜单&#xff0c;进行操作选择&#xff08;1查找图书、2借阅图书.....…...

命令模式介绍及应用案例

命令模式介绍 命令模式&#xff08;Command Pattern&#xff09; 是一种行为设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使你可以用不同的请求对客户进行参数化&#xff0c;并且支持请求的排队、记录日志、撤销操作等功能。命令模式的核心思想是将“请求”封…...

多线程(多线程案例)(续~)

目录 一、单例模式 1. 饿汉模式 2. 懒汉模式 二、阻塞队列 1. 阻塞队列是什么 2. 生产者消费者模型 3. 标准库中的阻塞队列 4. 自实现阻塞队列 三、定时器 1. 定时器是什么 2. 标准库中的定时器 欢迎观看我滴上一篇关于 多线程的博客呀&#xff0c;直达地址&#xf…...

python笔记之函数

函数初探 python在要写出函数很简单&#xff0c;通过关键字def即可写出&#xff0c;简单示例如下 def add(a, b):return ab 以上即可以定义出一个简单的函数&#xff1a;接收两个变量a和b&#xff0c;返回a和b相加的结果&#xff0c;当然这么说也不全对&#xff0c;原因就是…...

合合信息大模型加速器2.0实测:当AI开始“读心术“与“考古“

凌晨三点的编辑部&#xff0c;我盯着屏幕上密密麻麻的财务报表和如天书般的专利图纸&#xff0c;感觉咖啡因正在大脑中上演"黑凤凰"式崩溃。这时&#xff0c;合合信息的AI助手突然开口&#xff1a;"您需要的是自动关联32个数据表&#xff0c;还是让模型直接生成…...

一个判断A股交易状态的python脚本

最近在做股票数据相关的项目&#xff0c;需要用到判断某一天某个时刻A股的状态&#xff0c;比如休市&#xff0c;收盘&#xff0c;交易中等&#xff0c;发动脑筋想了一下&#xff0c;这个其实还是比较简单的&#xff0c;这里我把实现方法分享给大家。 思路 当天是否休市 对于某…...

【go】数组与切片

数组Array 重点&#xff1a; 数组是值类型 数组的定义 var 数组名 [数组大小] 数据类型,例如var intArr [5] int&#xff0c;定义完数组后数组里的元素有默认值。、 数组的地址&intArr、&intArr[0]。 数组占据连续的内存。 int通常是4字节&#xff08;32位&…...

hadoop集群配置-scp命令

scp 命令用于在不同主机之间复制文件或目录&#xff0c;在Hadoop集群配置中常用于将配置文件或相关资源分发到各个节点。以下是 scp 命令的基本用法和在Hadoop集群配置中的示例&#xff1a; 基本语法 scp [-r] [源文件或目录] [目标用户目标主机:目标路径] - -r &#xff1a;…...

闪记(FlashNote):让灵感快速成文的轻量级笔记工具

闪记&#xff08;FlashNote&#xff09;&#xff1a;让灵感快速成文的轻量级笔记工具 你是否经常遇到这样的情况&#xff1a;桌面上放了一大堆的新建123.txt&#xff0c;想记录一个想法&#xff0c;应该是一键开个一个快捷键然后瞬间记录就自动保存了&#xff0c;现在的很多笔记…...

打车APP订单系统逻辑梳理与实现

一、逻辑分析 打车 APP 订单系统是整个打车业务的核心&#xff0c;负责处理从乘客下单到行程结束的一系列流程&#xff0c;涉及乘客、司机和平台三方的交互。 乘客端 下单&#xff1a;乘客打开 APP&#xff0c;输入上车地点、目的地&#xff0c;选择车型等信息后提交订单。此时…...

《大模型部署》——ollama下载及大模型本地部署(详细快速部署)

ollama Ollama 是一款开源跨平台的大语言模型&#xff08;LLM&#xff09;运行工具&#xff0c;旨在简化本地部署和管理 AI 模型的流程。 下载ollama 进入官网下载https://ollama.com/ 选择需要的系统下载 下载完成后直接进行安装 下载大模型 选择想要部署的模型&#…...

【蓝桥杯速成】| 17.完全背包(一维easy版)

题目一&#xff1a;爬楼梯 问题描述 57. 爬楼梯&#xff08;第八期模拟笔试&#xff09; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬至多m (1 < m < n)个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 注意&#xff1a;给定 n 是一个正整…...

移动端六大语言速记:第4部分 - 数据结构

移动端六大语言速记&#xff1a;第4部分 - 数据结构 本文对比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift这六种移动端开发语言的数据结构特性&#xff0c;帮助开发者快速掌握各语言的语法差异。 4. 数据结构 4.1 数组与列表 各语言数组与列表的语法对比&#xff1…...

开源鸿蒙分布式软总线技术研究报告

引言 在现代计算环境中&#xff0c;分布式系统的重要性日益凸显&#xff0c;尤其是在物联网&#xff08;IoT&#xff09;和无处不在的连接的背景下。各种智能设备数量的爆炸式增长以及用户对跨设备无缝体验的需求&#xff0c;推动了分布式操作系统的发展。开源鸿蒙正是在这样的…...

Geotools结合SLD实现矢量中文标注下的乱码和可用字体解析

目录 前言 一、需求溯源 1、原始的SLD渲染 2、最初的效果 二、问题修复 1、还是字符编码 2、如何选择可用的字体 3、如何查看支持的字体库 三、总结 前言 随着地理信息系统&#xff08;GIS&#xff09;技术的不断发展&#xff0c;矢量数据的可视化和标注成为了地理信息展…...

linux 服务器创建服务器启动后服务自启动

1、在/etc/systemd/system/下touch一个文件&#xff1a; touch /etc/systemd/system/your_application.service 2、在文件中写入&#xff1a; [Unit] Descriptionmodules-system Aftersyslog.target[Service] Typeforking Userroot Grouproot ExecStart/bin/bash /usr/loca…...

基于Python与CATIA V5的斐波那契螺旋线自动化建模技术解析

引言 斐波那契螺旋线&#xff08;Fibonacci Spiral&#xff09;作为自然界广泛存在的黄金比例曲线&#xff0c;在工业设计、产品造型、机械工程等领域具有重要应用价值。本文将以Python控制CATIA V5进行参数化建模为例&#xff0c;深入解析三维CAD环境中复杂数学曲线的自动化生…...

动态规划(11.按摩师)

题目链接&#xff1a;面试题 17.16. 按摩师 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; 状态表示&#xff1a; 对于简单的线性 dp &#xff0c;我们可以⽤「经验 题⽬要求」来定义状态表⽰&#xff1a; 以某个位置为结尾&#xff0c;巴拉巴拉&#xff1b;…...

CentOS下安装Docker,Docker下安装JDK\MYSQL\REDIS\NGINX

先用VM安装好Centos8.5&#xff0c;可以选择安装迷你版&#xff0c;我安装的是UI版。 然后用MobaXterm_Portable_v23.0_cn连上去&#xff0c;互访成功就可以往下操作。 1. 修改文件&#xff1a;就是要把之前的mirror替换成现在的vault cd /etc/yum.repos.d/sed -i s/mirrorl…...

demo.launch(inbrowser=True, share=True)无法生成共享网址

Gradio 的共享功能无法正常工作&#xff0c;原因是缺少一个名为 frpc_windows_amd64_v0.3 用到代码 app.demo.launch(show_errorTrue, inbrowserTrue, shareTrue) show_errorTrue&#xff1a;这个参数的作用是当应用在启动过程中出现错误时&#xff0c;会显示错误信息。这对于调…...

翻译: 人工智能如何让世界变得更美好二

Basic assumptions and framework 基本假设和框架 To make this whole essay more precise and grounded, it’s helpful to specify clearly what we mean by powerful AI (i.e. the threshold at which the 5-10 year clock starts counting), as well as laying out a fram…...

【vue】editor富文本输入全英文,谷歌浏览器:元素不会自动换行bug

【vue】editor富文本输入全英文&#xff0c;谷歌浏览器&#xff1a;元素不会自动换行bug 解决方案&#xff1a;给元素一个宽度 100% .editor {width: 100%; }...