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

news/2025/2/26 10:04:33

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.niftyadmin.cn/n/5868521.html

相关文章

架构思维:架构的演进之路

文章目录 引言为什么架构思维如此重要架构师的特点软件架构的知识体系如何提升架构思维大型互联网系统架构的演进之路一、大型互联网系统的特点二、系统处理能力提升的两种途径三、大型互联网系统架构演化过程四、总结 引言 在软件开发行业中&#xff0c;有很多技术人可能会问…

1.4常规es报错问题

问题一&#xff1a;unable to install syscall filter [2016-11-06T16:27:21,712][WARN ][o.e.b.JNANatives ] unable to install syscall filter: Java.lang.UnsupportedOperationException: seccomp unavailable: requires kernel 3.5 with CONFIG_SECCOMPandCONFIG_SECCOM…

PCEP使用

PCEP&#xff08;Path Computation Element Protocol&#xff09;主要用于网络中路径计算的请求和响应&#xff0c;特别是在多协议标签交换&#xff08;MPLS&#xff09;和光网络等环境中。以下是 PCEP 的使用方法和步骤&#xff1a; PCEP 的使用步骤 环境准备&#xff1a; 确…

idea + Docker + 阿里镜像服务打包部署

一、下载docker desktop软件 官网下载docker desktop&#xff0c;需要结合wsl使用 启动成功的画面(如果不是这个画面例如一直处理start或者是stop需要重新启动&#xff0c;不行就重启电脑) 打包成功的镜像在这里&#xff0c;如果频繁打包会导致磁盘空间被占满&#xff0c;需…

视频裂变加群推广分享引流源码

源码介绍 视频裂变加群推广分享引流源码 最近网上很火&#xff0c;很多人都在用&#xff0c;适合引流裂变推广 测试环境&#xff1a;PHP7.4(PHP版本不限制) 第一次访问送五次观看次数&#xff0c;用户达到观看次数后需要分享给好友或者群,好友必须点击推广链接后才会增加观看次…

深入解析提示词:从基础到结构化应用

在人工智能蓬勃发展的当下&#xff0c;提示词&#xff08;Prompt&#xff09;扮演着至关重要的角色。无论是在与聊天机器人交流&#xff0c;还是驱动复杂智能体完成任务&#xff0c;精准且高效的提示词都能起到事半功倍的效果。本文将带你全面了解提示词&#xff0c;深入探索结…

Flutter - 基础Widget

Flutter 中万物皆 Widget&#xff0c;基础Widget 同步对应 Android View. 普通文本 Text /*** 控制文本样式统一使用 style:TextStyle, 例&#xff1a;fontSize(字体大小),color(颜色),shadows(阴影)等等* 控制文本布局需单独设置&#xff1a;* textAlign(文不对齐方式)* te…

【论文学习】DeepSeek-V3 总结

文章目录 Abstract1. Introduction2. Architecture2.1 Basic Architecture2.2 Multi-Token Prediction 3. Infrastructures3.1 Compute Clusters3.2 Training Framework3.3 FP8 Training 4. Pre-Training4.1 Data Construction4.2 Hyper-Parameters4.3 Long Context Extension4…