蓝桥杯 Java B 组之记忆化搜索(滑雪问题、斐波那契数列)

server/2025/2/28 13:46:02/

Day 5:记忆化搜索(滑雪问题、斐波那契数列)


📖 一、记忆化搜索简介

记忆化搜索(Memoization) 是一种优化递归的方法,它利用 哈希表(HashMap)或数组 存储已经计算过的结果,避免重复计算,提高效率。

📌 记忆化搜索 vs 动态规划

方法特点适用场景
记忆化搜索自顶向下(递归 + 记忆化存储)递归问题
动态规划自底向上(迭代 + 状态转移)适用于所有 DP 问题

📖 二、经典记忆化搜索问题

1. 滑雪问题

题目描述

  • 给定一个 n × m 的矩阵,每个位置 (i, j) 代表海拔高度 h(i, j)
  • 从某一点 (i, j) 出发,可以向 上下左右 移动,前提是新的位置海拔严格低于当前点。
  • 目标是求最长的滑雪路径长度

🔹 1. 思路

  • 递归搜索所有可能的路径。
  • 由于路径可能会重复访问同一个点,我们用 dp[i][j] 记忆化存储 (i, j) 位置的最长滑雪路径

🔹 2. 代码实现(滑雪问题)

import java.util.*;public class Skiing {static int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};static int[][] grid, dp;static int rows, cols;public static int longestSkiPath(int[][] matrix) {if (matrix == null || matrix.length == 0) return 0;rows = matrix.length;cols = matrix[0].length;grid = matrix;dp = new int[rows][cols];int maxPath = 0;for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {maxPath = Math.max(maxPath, dfs(i, j));}}return maxPath;}private static int dfs(int i, int j) {if (dp[i][j] != 0) return dp[i][j]; // 记忆化:避免重复计算int maxLength = 1; // 初始长度for (int[] dir : directions) {int x = i + dir[0], y = j + dir[1];if (x >= 0 && x < rows && y >= 0 && y < cols && grid[x][y] < grid[i][j]) {maxLength = Math.max(maxLength, 1 + dfs(x, y));}}dp[i][j] = maxLength;return maxLength;}public static void main(String[] args) {int[][] matrix = {{9, 8, 7},{6, 5, 4},{3, 2, 1}};System.out.println("最长滑雪路径长度: " + longestSkiPath(matrix)); // 输出 9}
}

🔹 3. 代码讲解

  1. dfs(i, j) 递归查找 (i, j) 位置的最长路径。
  2. dp[i][j] 记忆化存储 计算过的路径,避免重复计算。
  3. 四个方向搜索,如果高度下降,则递归搜索。

✅ 时间复杂度:O(n × m)(避免重复计算)。


📖 三、斐波那契数列(Fibonacci)

题目描述: 斐波那契数列定义如下:

F(n)=F(n−1)+F(n−2),F(0)=0,F(1)=1F(n) = F(n-1) + F(n-2), \quad F(0) = 0, \quad F(1) = 1

F(n)


🔹 1. 代码实现(记忆化搜索版)

import java.util.*;public class FibonacciMemoization {static Map<Integer, Long> memo = new HashMap<>();public static long fibonacci(int n) {if (n == 0) return 0;if (n == 1) return 1;if (memo.containsKey(n)) return memo.get(n);long result = fibonacci(n - 1) + fibonacci(n - 2);memo.put(n, result);return result;}public static void main(String[] args) {System.out.println("Fibonacci(50): " + fibonacci(50)); // 输出很快}
}

✅ 时间复杂度:O(n),避免 O(2^n) 的指数级递归。


📖 四、蓝桥杯真题:2021省赛 - 冰雹数

题目描述: 冰雹数列定义如下:

  • Hail(n) = n / 2(如果 n 是偶数)。
  • Hail(n) = 3n + 1(如果 n 是奇数)。
  • 继续计算直到 n = 1,求 Hail(n) 的长度。

示例

输入: 10
输出: 7

🔹 1. 代码实现(记忆化搜索)

import java.util.*;public class HailstoneSequence {static Map<Integer, Integer> memo = new HashMap<>();public static int hailstoneLength(int n) {if (n == 1) return 1;if (memo.containsKey(n)) return memo.get(n);int next = (n % 2 == 0) ? n / 2 : 3 * n + 1;int length = 1 + hailstoneLength(next);memo.put(n, length);return length;}public static void main(String[] args) {int n = 10;System.out.println("冰雹数列长度: " + hailstoneLength(n)); // 输出 7}
}

🔹 2. 代码讲解

  1. hailstoneLength(n) 递归计算 n 的冰雹序列长度。
  2. memo 记忆化存储 已计算的 n,避免重复计算。

✅ 时间复杂度:O(n),避免 O(2^n) 级别的计算。


📖 五、总结

1. 记忆化搜索 vs 动态规划

方法优点缺点
记忆化搜索(自顶向下)直观,递归写法清晰可能有递归栈溢出
动态规划(自底向上)迭代方式,减少递归栈使用需要找到最优状态转移方程

2. 记忆化搜索应用场景

斐波那契数列:避免指数级递归。
最长路径问题(滑雪):存储已访问路径,避免重复计算。
数论问题(冰雹数):存储已计算结果,避免深度递归。


http://www.ppmy.cn/server/171303.html

相关文章

脑机接口SSVEP经典算法 ITCCA个体模板典型相关分析 matlab实战

文章目录 前言一、ItCCA的进步二、在C-VEP的应用1.C-VEP介绍2.应用方法 三、在SSVEP的应用1.标准CCA模板的局限2. 实验结果&#xff1a;ITCCA的优势 四、matlab实现 前言 itCCA最开始用于C-VEP(code modulated VEP)信号的解码&#xff0c;这种信号的特征难以用正余弦波去描述&a…

Anaconda安装 超详细版 (2025版)

目录 第一步&#xff1a;下载anaconda安装包 官网下载&#xff1a;Anaconda | Built to Advance Open Source AI 清华大学镜像站下载&#xff08;速度较快&#xff09; 第二步&#xff1a;安装anaconda 第三步&#xff1a;验证安装 扩展 创建conda基本环境 激活conda环…

基础设施安全(Infrastructure Security)是什么?

基础设施安全&#xff08;Infrastructure Security&#xff09;指的是保护IT基础设施&#xff08;包括物理和云端的服务器、网络设备、存储、数据库等&#xff09;免受网络攻击、数据泄露、未授权访问、系统故障等威胁的各种安全措施和技术。 1. 基础设施安全的主要组成部分 &…

十一、k8s安全机制

k8s作为一个分布式的微服务管理系统&#xff0c;保证集群安全是一个非常重要的任务&#xff0c; 核心-----------api-server 我们围绕集群权限的设置&#xff0c;其实就是设置api-server权限。 围绕api-server的权限机制&#xff0c;分为三个步骤&#xff1a; 1、认证------…

如何通过JS实现关闭网页时清空该页面在本地电脑的缓存存储?

要通过JavaScript实现关闭网页时清空该页面在本地电脑的缓存存储&#xff0c;可以采用以下方法&#xff1a; 使用window.onbeforeunload事件监听器&#xff1a; 在Vue.js应用中&#xff0c;可以在App.vue组件的mounted生命周期钩子中监听window.onbeforeunload事件&#xff0c…

Python连接SQL SEVER数据库全流程

背景介绍 在数据分析领域&#xff0c;经常需要从数据库中获取数据进行分析和处理。而SQL Server是一种常用的关系型数据库管理系统&#xff0c;因此学习如何使用Python连接SQL Server数据库并获取数据是非常有用的。 以下是Python使用pymssql连接SQL Server数据库的全流程&a…

【FL0086】基于SSM和微信小程序的垃圾分类小程序

&#x1f9d1;‍&#x1f4bb;博主介绍&#x1f9d1;‍&#x1f4bb; 全网粉丝10W,CSDN全栈领域优质创作者&#xff0c;博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发…

在PyTorch使用UNet进行图像分割【附源码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…