算法:记忆化搜索

文章目录

  • 记忆化搜索
    • 斐波那契数列
  • 例题
    • 不同路径
    • 最长递增子序列
    • 猜数字大小
    • 矩阵中的最长递增路径

记忆化搜索的原理其实很简单,简单来说就是对暴力搜索的一些优化,因此整体上来讲难度不高

记忆化搜索

所谓记忆化搜索,直白来说就是一个带有备忘录的递归

如何实现记忆化搜索?

  1. 添加一个备忘录
  2. 递归每次返回的时候,都把结果放在备忘录当中
  3. 每次进行递归前,都到备忘录中看一看

下面用一个经典题目诠释记忆化搜索的意义

斐波那契数列

在这里插入图片描述

  1. 递归
class Solution 
{
public:// 递归int fib(int n) {if(n == 0 || n == 1) return n;return fib(n - 1) + fib(n - 2);}
};
  1. 动态规划
class Solution 
{
public:// 动态规划int fib(int n) {if(n == 0 || n == 1)return n;vector<int> v(n + 1);v[0] = 0, v[1] = 1;for(int i = 2; i <= n; i++)v[i] = v[i - 1] + v[i - 2];return v[n];}
};
  1. 记忆化搜索
class Solution 
{
public:// 记忆化搜索int memo[31];int fib(int n) {// 先到备忘录中看看if(memo[n] != 0)return memo[n];if(n == 0 || n == 1){memo[n] = n;return memo[n];}return fib(n - 1) + fib(n - 2);}
};

从上面这个例题能感觉出来,记忆化搜索其实就是在递归的基础上进行了一些优化,没有什么本质性的新增内容,基于这个原因,用下面的例题来进一步学习记忆化搜索

例题

不同路径

在这里插入图片描述
暴力搜索

class Solution 
{
public:int dfs(int m, int n, int p, int q){if(m > p || n > q) return 0;if(m == p && n == q) return 1;return dfs(m + 1, n, p, q) + dfs(m, n + 1, p, q);}int uniquePaths(int m, int n) {return dfs(0, 0, m - 1, n - 1);}
};

采用记忆化搜索进行一定程度的优化

class Solution 
{
public:int arr[101][101];int dfs(int m, int n, int p, int q){if(arr[m][n] != 0) return arr[m][n];if(m > p || n > q) return 0;if(m == p && n == q) return 1;int down = dfs(m + 1, n, p, q);int right = dfs(m, n + 1, p, q);arr[m + 1][n] = down;arr[m][n + 1] = right;return down + right;}int uniquePaths(int m, int n) {return dfs(0, 0, m - 1, n - 1);}
};

最长递增子序列

在这里插入图片描述

暴力搜索

class Solution
{
public:vector<int> path;int maxSize;int lengthOfLIS(vector<int>& nums){dfs(0, nums, INT_MIN);return maxSize;}void dfs(int pos, vector<int>& nums, int prev){maxSize = max(maxSize, (int)path.size());for (int i = pos; i < nums.size(); i++){if (nums[i] > prev){path.push_back(nums[i]);dfs(i + 1, nums, nums[i]);path.pop_back();}}}
};

记忆化搜索

class Solution 
{
public:int memo[2501];int lengthOfLIS(vector<int>& nums) {int ret = 0;for(int i = 0; i < nums.size(); i++){ret = max(ret, dfs(i, nums));}return ret;}int dfs(int pos, vector<int>& nums){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(i, nums) + 1);}}memo[pos] = ret;return ret;}
};

猜数字大小

在这里插入图片描述
暴力搜索

class Solution 
{
public:int getMoneyAmount(int n) {return dfs(1, n);}int dfs(int begin, int end){if(begin >= end) return 0;int res = INT_MAX;// 选一个节点作为根节点for(int i = begin; i <= end; i++){// 找左子树花费的钱int left = i + dfs(begin, i - 1);// 找右子树花费的钱int right = i + dfs(i + 1, end);res = min(res, max(left, right));}return res;}
};

记忆化搜索优化

class Solution 
{
public:vector<vector<int>> memo;int getMoneyAmount(int n) {memo.resize(n + 1, vector<int>(n + 1));return dfs(1, n);}int dfs(int begin, int end){if(begin >= end) return 0;if(memo[begin][end] != 0) return memo[begin][end];int res = INT_MAX;// 选一个节点作为根节点for(int i = begin; i <= end; i++){// 找左子树花费的钱int left = i + dfs(begin, i - 1);// 找右子树花费的钱int right = i + dfs(i + 1, end);res = min(res, max(left, right));}memo[begin][end] = res;return res;}
};

矩阵中的最长递增路径

在这里插入图片描述
记忆化搜索

class Solution 
{
public:int m, n;int dx[4] = {0, 0, 1, -1};int dy[4] = {1, -1, 0, 0};vector<vector<int>> memo;int longestIncreasingPath(vector<vector<int>>& matrix) {m = matrix.size();n = matrix[0].size();memo.resize(m, vector<int>(n));int res = 0;for(int i = 0; i < m; i++){for(int j = 0; j < n; j++){res = max(res, dfs(i, j, matrix));}}return res;}// 从第i行和第j列的这个元素开始的最长递增路径int dfs(int i, int j, vector<vector<int>>& matrix){if(memo[i][j] != 0) return memo[i][j];int ret = 1;// 长度等于其四周的元素的最长递增路径for(int k = 0; k < 4; k++){int x = i + dx[k], y = j + dy[k];// 如果坐标合法并且是递增if(x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] > matrix[i][j]){ret = max(ret, 1 + dfs(x, y, matrix));}}memo[i][j] = ret;return ret;}
};

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

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

相关文章

《轻购优品》新零售玩法:消费积分认购+众筹新玩法

《轻购优品》新零售玩法&#xff1a;消费积分认购众筹新玩法 引言&#xff1a;2023年开年已来&#xff0c;政府的工作报告提出“把恢复和扩大消费摆在优先位置”&#xff0c;并且把2023年定位为“消费提振年”&#xff0c;以“全年乐享全年盛惠”为主题多地政府共同发力&#x…

亚马逊云科技AI创新应用下的托管在AWS上的数据可视化工具—— Amazon QuickSight

目录 Amazon QuickSight简介 Amazon QuickSight的独特之处 Amazon QuickSight注册 Amazon QuickSight使用 Redshift和Amazon QuickSightt平台构建数据可视化应用程序 构建数据仓库 数据可视化 Amazon QuickSight简介 亚马逊QuickSight是一项可用于交付的云级商业智能 (BI…

架构师篇 DDD领域驱动设计篇

一 DDD领域驱动设计 1.1 领域驱动设计 领域驱动设计(英文&#xff1a;Domain-Driven Design&#xff0c;缩写DDD)是一种模型驱动设计的方法&#xff0c;领域驱动设计常以战略设计与战术设计来将整个领域展现的淋漓尽致&#xff0c;其作用范围既面向业务也面向技术。从战略角度…

PS学习笔记——视图调整

文章目录 图片拖动图片旋转图片缩放 视图只是我们在对图片进行操作时所看到的图片状态&#xff0c;并不会实际改变图片的属性。目的是方便我们在操作图片时有最舒服的体验 图片拖动 工具栏中有这样一个抓手工具(快捷键H)&#xff0c;选择这个抓手工具便可以在图片放大后能用鼠标…

代码随想录算法训练营第五十七天丨 动态规划part17

647. 回文子串 思路 动态规划 动规五部曲&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 如果大家做了很多这种子序列相关的题目&#xff0c;在定义dp数组的时候 很自然就会想题目求什么&#xff0c;我们就如何定义dp数组。 绝大多数题目确实是…

Leetcode——最长递增子序列

1. 题目链接&#xff1a;300. 最长递增子序列 2. 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&a…

F. Alex‘s whims Codeforces Round 909 (Div. 3) 1899F

Problem - F - Codeforces 题目大意&#xff1a;有q次询问&#xff0c;每次询问给出一个数x&#xff0c;要求构造一棵n个点的树&#xff0c;使得对于每次询问&#xff0c;树上都有一条简单路径的长度等于x&#xff0c;同时每次询问前可以对树进行一次操作&#xff0c;即将一个…

泛微E-Cology CheckServer.jspSQL注入漏洞(QVD-2023-9849) 复现

泛微E-Cology CheckServer.jspSQL注入漏洞(QVD-2023-9849) 复现 1.漏洞描述 泛微 Ecology OA 系统对用户传入的数据过滤处理不当&#xff0c;导致存在 SQL 注入漏洞&#xff0c;未经过身份认证的远程攻击者可利用此漏洞执行任意SQL指令&#xff0c;从而窃取数据库敏感信息。 …

使用ADS进行serdes仿真时,Tx_Diff中EQ的设置对发送端波形的影响。

研究并记录一下ADS仿真中Tx_Diff的EQ设置。原理图如下&#xff1a; 最上面是选择均衡方法Choose equalization method&#xff1a;Specify FIR taps&#xff0c;Specify de-emphasis和none。 当选择Specify de-emphasis选项时&#xff0c;下方可以输入去加重具体的dB值&#x…

typora使用PicGo自动上传图片到chevereto图床

typora使用PicGo自动上传图片到chevereto图床 近期发现&#xff0c;gitee图床不能用了。github又涉及科学上网。搜索了开源图床方案&#xff0c;找到了chevereto&#xff0c;使用起来还不错。分享给大家。 文章目录 typora使用PicGo自动上传图片到chevereto图床chevereto图床安…

java使用 TCP 的 Socket API 实现客户端服务器通信

一&#xff1a;什么是 Socket(套接字) Socket 套接字是由系统提供于网络通信的技术, 是基于 TCP/IP 协议的网络通信的基本操作&#xff0c;要进行网络通信, 需要有一个 socket 对象, 一个 socket 对象对应着一个 socket 文件, 这个文件在 网卡上而不是硬盘上, 所以有了 sokcet…

ForkLift:macOS文件管理器/FTP客户端

ForkLift 是一款macOS下双窗口的文件管理器&#xff0c;可以代替本地的访达。ForkLift同时具备连接Ftp、SFtp、WebDav以及云服务器。 ForkLift还具备访达不具备的小功能&#xff0c;比如从文件夹位置打开终端&#xff0c;显示隐藏文件&#xff0c;制作替换等功能。ForkLift 是一…