【C++刷题】优选算法——递归第四辑

news/2025/1/15 23:44:30/

记忆化搜索篇

  • 什么是记忆化搜索?
    • 带 备忘录 的递归
  • 如何实现记忆化搜索?
    • a.添加一个备忘录 <可变参数,返回值>
    • b.每次递归返回的时候,把结果放到备忘录里
    • c.每次递归进入的时候,先查看一下备忘录
  • 记忆化搜索 vs 常规动态规划:
    • 相同点:
      • 都是暴力解法(暴搜)
      • 优化方式都是把已经计算出的结果存起来
    • 不同点:
      • 记忆化搜索是递归形式
      • 常规动态规划是递推(循环)形式

问题:

  • 所有的递归(暴搜、深搜),都能改成记忆化搜索吗?
    不是的。 只有在递归的过程中,出现了大量完全相同的问题时,才能用记忆化搜索的方式优化。
  • 以 暴搜->记忆化搜索->动态规划 的流程思路来解决动态规划问题,一定程度上是可行的。暴搜的阶段也可以为确定状态表示,提供一个参考方向。
  1. 斐波那契数
// 1 - 递归
int dfs(int n)
{if(n == 0 || n == 1) return n;return dfs(n-1) + dfs(n-2);
}
int fib(int n)
{return dfs(n);
}// 2 - 记忆化搜索
unordered_map<int, int> memo; // 创建备忘录
int dfs(int n)
{if(n == 0 || n == 1){if(!memo.count(n)) memo[n] = n; // 返回之间添加备忘录return n;}if(memo.count(n)) return memo[n]; // 进入之前查看备忘录else{memo[n] = dfs(n-1) + dfs(n-2);return memo[n];}}
int fib(int n)
{return dfs(n);
}// 3 - 动态规划
int fib(int n)
{// 0.预处理if(n == 0 || n == 1) return n;// 1.dp数组vector<int> dp(n + 1, 0);// 2.初始化dp[1] = 1;// 3.状态转移方程for(int i = 2; i < dp.size(); ++i){dp[i] = dp[i-1] + dp[i-2];}// 4.返回值return dp.back();
}
  1. 不同路径
// 1 - 记忆化搜索
vector<vector<int>> memo;
int dfs(int i, int j)
{if(i == 0 || j == 0){memo[i][j] = 1;return 1;}if(memo[i][j] == 0) memo[i][j] = dfs(i - 1, j) + dfs(i, j - 1);return memo[i][j];
}
int uniquePaths(int m, int n)
{memo = vector<vector<int>>(m, vector<int>(n, 0));return dfs(m-1, n-1);
}// 2 - 动态规划
int uniquePaths(int m, int n)
{// 1.dp数组vector<vector<int>> dp(m, vector<int>(n));// 2.初始化for (int i = 0; i < m; ++i){dp[i][0] = 1;}for (int i = 0; i < n; ++i){dp[0][i] = 1;}// 3.状态转移方程for (int row = 1; row < m; ++row){for (int col = 1; col < n; ++col){dp[row][col] = dp[row - 1][col] + dp[row][col - 1];}}// 4.返回值return dp.back().back();
}
  1. 最长递增子序列
vector<int> memo;
int dfs(vector<int>& nums, int step)
{if(memo[step] != 0) return memo[step];int ret = 1;for(int i = step + 1; i < nums.size(); ++i){if(nums[i] > nums[step]){ret = max(ret, dfs(nums, i) + 1);}}memo[step] = ret;return ret;
}
int lengthOfLIS(vector<int>& nums)
{memo = vector<int>(nums.size(), 0);int ret = 0;for(int i = 0; i < nums.size(); ++i){ret = max(ret, dfs(nums, i));}return ret;
}
  1. 猜数字大小 II
vector<vector<int>> memo;
int dfs(int start, int end)
{if(start >= end) return 0;if(memo[start][end] != -1) return memo[start][end];int ret = INT_MAX;for(int i = start; i <= end; ++i){ret = min(ret, i + max(dfs(start, i - 1), dfs(i + 1, end)));}memo[start][end] = ret;return ret;
}
int getMoneyAmount(int n)
{memo = vector<vector<int>>(n+1, vector<int>(n+1, -1));return dfs(1, n);
}
  1. 矩阵中的最长递增路径
unordered_multimap<int, int> direction = {{0, 1},{0, -1},{1, 0},{-1, 0}
};
vector<vector<int>> memo;
int dfs(vector<vector<int>>& matrix, int i, int j)
{if(memo[i][j] != -1) return memo[i][j];int ret = 0;for(auto& e : direction){int x = i + e.first, y = j + e.second;if((x >= 0 && x < matrix.size())&& (y >= 0 && y < matrix[0].size())&& (matrix[x][y] > matrix[i][j])){ret = max(ret, 1 + dfs(matrix, x, y));}}memo[i][j] = ret;return ret;
}
int longestIncreasingPath(vector<vector<int>>& matrix)
{int m = matrix.size();int n = matrix[0].size();memo = vector<vector<int>>(m, vector<int>(n, -1));int ret = 0;for(int i = 0; i < m; ++i){for(int j = 0; j < n; ++j){ret = max(ret, 1 + dfs(matrix, i, j));}}return ret;
}

http://www.ppmy.cn/news/1463542.html

相关文章

Flutter 中的 TextButton 小部件:全面指南

Flutter 中的 TextButton 小部件&#xff1a;全面指南 在Flutter的世界里&#xff0c;TextButton是一个基础的小部件&#xff0c;用于创建只包含文本的按钮。它通常用于对话框、表单以及需要强调主要操作的界面。本文将为您提供一个全面的指南&#xff0c;帮助您了解如何使用T…

Flutter 中的 AnimatedSize 小部件:全面指南

Flutter 中的 AnimatedSize 小部件&#xff1a;全面指南 在Flutter中&#xff0c;动画是增强用户界面和提供流畅用户体验的强大工具。AnimatedSize是一个用于动画化其子组件大小变化的组件&#xff0c;它可以在大小改变时添加动画效果&#xff0c;使得界面更加生动有趣。本文将…

AIGC 008-IP-Adapter文本兼容图像提示适配器用于文本到图像扩散模型

AIGC 008-IP-Adapter文本兼容图像提示适配器用于文本到图像扩散模型&#xff01; 文章目录 0 论文工作1 论文方法2 效果 0 论文工作 这篇论文介绍了 IP-Adapter&#xff0c;一种 高效地将预训练的图像到图像转换模型适应到新领域 的方法。它通过在预训练模型的 输入端 添加一个…

基于Django的图书管理系统

文章目录 前言一、页面展示1.登录2.前端页面3.后端页面 二、项目上传&#xff08;1&#xff09;导入数据库&#xff08;2&#xff09;导入项目&#xff08;3&#xff09;数据库密码修改&#xff08;4&#xff09;进入网站 总结 前言 本网站调用Django编写了图书管理网站&#…

MongoDB CRUD操作:内嵌文档数组查询

MongoDB 内嵌文档数组查询 文章目录 MongoDB 内嵌文档数组查询查询数组内嵌文档为文档数组中的字段指定查询条件指定文档数组内嵌文档字段的查询条件使用数组索引查询内嵌文档的字段 为文档数组指定多个条件单个内嵌文档满足内嵌字段的多个查询条件符合标准的元素组合 使用 Mon…

Java_IO流学习

IO流 概念 I – in – 输入(读) O – out – 输出(写) 流 – 一点一点的像水流一样去传输数据 注意&#xff1a;站在程序的角度去看待输入还是输出 分类 按照方向分流&#xff1a;输入流、输出流 按照单位分流&#xff1a;字节流、字符流 按照功能分流&#xff1a;基础流/节点…

2024电工杯数学建模A题思路+模型+代码

2024电工杯数学建模A题思路模型代码&#xff0c;开赛后第一时间更新&#xff0c;更新见文末名片 以下为2023年电工杯A提思路&#xff1a; A题: 电采暖负荷参与电力系统功率调节的技术经济分析。 典型住户电采暖负荷用电行为分析&#xff1a; a) 分析典型房间温变过程微分方程…

aws eks节点的初始化引导和鉴权逻辑

kubernetes集群的kubelet的启动引导eks集群的kubelet启动引导 参考资料 https://juejin.cn/post/7016472622246395934eks安全最佳实践&#xff0c;https://aws.github.io/aws-eks-best-practices/security/docs/iam/ kubernetes集群的kubelet的启动引导 按照官方文档和相关…