当前位置:首页 > 牛客 > 牛客233065题:最长滑雪路径的动态规划与记忆化搜索解法

牛客233065题:最长滑雪路径的动态规划与记忆化搜索解法

5个月前 (08-27)

牛客233065题:最长滑雪路径的动态规划与记忆化搜索解法 动态规划 记忆化搜索 深度优先搜索 深搜 DFS 递归 C++ 牛客题解 第1张

一、题目解读

牛客233065题要求求解给定矩阵中的最长滑雪路径。滑雪者从任意点出发,每次只能向高度严格递减的相邻格子移动(上下左右四个方向),需找到路径长度最大值。题目考察动态规划与搜索算法的结合,重点在于优化重复计算以提高效率。

二、解题思路

采用深度优先搜索DFS)结合记忆化技术解决该问题。核心思路如下:

1. 记忆化搜索:为避免重复计算每个点的最长路径,使用二维备忘录记录已求解结果。

2. 递归式设计:从每个点出发递归搜索四周符合条件的低高度点,路径长度为其后继点最长路径+1。

3. 边界条件:严格检查矩阵边界及高度递减要求,确保路径合法性。

通过动态规划的思想,将递归搜索转化为有记忆的优化算法,显著降低时间复杂度。

三、解题步骤

1. 初始化:读取矩阵尺寸,创建与矩阵同大小的备忘录(全0表示未计算)。

2. 外层循环:遍历矩阵每个点作为起点,调用DFS函数更新最长路径结果。

3. DFS函数:

    若当前点已计算,直接返回备忘录值。

    遍历四个方向,对合法相邻点(边界内且高度递减)递归调用DFS,获取其最长路径。

    更新当前点的路径长度为所有后继点路径最大值+1,存入备忘录。

4. 结果汇总:外层循环结束后,备忘录中存储了所有点的最长路径,取全局最大值即为答案。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int dirs[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; // 四个方向

int dfs(vector<vector<int>>& matrix, vector<vector<int>>& memo, int i, int j) {
    if(memo[i][j]!= 0) return memo[i][j]; // 已计算过,直接返回结果
    
    int max_len = 1; // 至少包含自己
    for(auto& dir : dirs) { // 遍历四个方向
        int x = i + dir[0], y = j + dir[1];
        // 边界检查且高度必须严格递减
        if(x >= 0 && x < matrix.size() && y >= 0 && y < matrix[0].size() 
           && matrix[x][y] < matrix[i][j]) {
            max_len = max(max_len, dfs(matrix, memo, x, y) + 1);
        }
    }
    memo[i][j] = max_len; // 记忆化存储当前点的最长路径
    return max_len;
}

int longestSkiPath(vector<vector<int>>& matrix) {
    if(matrix.empty()) return 0;
    int n = matrix.size(), m = matrix[0].size();
    vector<vector<int>> memo(n, vector<int>(m, 0)); // 初始化备忘录
    int res = 0;
    
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            res = max(res, dfs(matrix, memo, i, j)); // 更新全局最长路径
        }
    }
    return res;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> matrix(n, vector<int>(m));
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            cin >> matrix[i][j];
        }
    }
    cout << longestSkiPath(matrix) << endl;
    return 0;
}

五、总结

该解法巧妙地将动态规划思想融入DFS,通过备忘录消除递归中的重复计算,将时间复杂度优化至O(NM)(N为矩阵行数,M为列数)。代码结构清晰,边界处理严谨,是解决此类路径问题的典型范例。实际应用中,记忆化搜索常作为优化递归算法的有效手段,值得深入掌握。


原创内容 转载请注明出处

分享给朋友:

相关文章

征服力扣704题:三步掌握经典二分查找算法

征服力扣704题:三步掌握经典二分查找算法

题目重解我们面对的是算法领域最经典的二分查找问题:在一个已排序的整数数组中,快速定位目标值的位置。就像在一本按字母顺序排列的字典中查找单词,我们不需要逐页翻阅,而是通过不断折半的方式快速缩小搜索范围,...

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

IOI 1994 洛谷1216:如何用O(1)空间解决数字三角形问题?附代码实现

题目重解:数字三角形是一个经典的动态规划问题,给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们需要找到一条路径,使得路径上经过的数字总和最大。这个问题可以很...

力扣94:递归之美 轻松掌握二叉树中序遍历

力扣94:递归之美 轻松掌握二叉树中序遍历

题目解读二叉树的中序遍历是一种基础且重要的树遍历方式,其遍历顺序为:先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。对于二叉搜索树,中序遍历的结果恰好是节点值的升序排列。给定一个二叉...

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

2024蓝桥杯省赛B组“传送阵”题解(C++代码+图论算法优化)

一、题目解读2024年蓝桥杯省B组“传送阵”题目要求处理一个包含n个节点的图,节点间存在单向传输关系。每个节点i可传送至a[i]指定的节点,形成可能存在的环结构。题目需求解从任意节点出发能到达的最长路...

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

一、题目解读LeetCode 120题“三角形最小路径和”要求给定一个由数字组成的三角形,从顶部开始向下移动,每次可向左或向右移动一格,计算从顶至底的最小路径和。三角形以二维向量形式给出,每层元素数量...

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

一、题目解读    “生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。