leetcode2684--矩阵中移动的最大次数

1. 题意

矩阵中一个位置只能从左上一、左、左下一格子转移而来,且当前值一定大于转移之前的值;

求从第一列开始的最大转移步数。

矩阵中移动的最大次数

2. 题解

  • 思路
    由于状态只能从左向右转移,所以同一个位置被搜索到后,第一列其他位置再搜索到它的距离一定相等。题目求得是第一列转移到其他位置的最大次数,我们需要把第一列置0,其他列置
    MINVAL。使得只有从第一列转移的才能使得值为正数。
cpp 复制代码
class Solution {
public:
    struct Dir {
        constexpr static int dir[][2] = {
            {1,-1},{0,-1},{-1,-1}
        };
    };
    int maxMoves(vector<vector<int>>& grid) {
        
        int w = grid[0].size();
        int h = grid.size();
        int MIN_VAL = -2000;
        int ans = 0;
        vector<vector<int>> dp(h, vector<int>(w, MIN_VAL));


        for (int i = 0;i < h; ++i)
            dp[i][0] = 0;

        for (int i = 1; i < w; ++i) {
            for (int j = 0;j < h; ++j) {

                for (auto &d:Dir::dir){
                    int px = j + d[0];
                    int py = i + d[1];

                    if (px < 0 || py < 0 || px > h - 1 || py > w - 1)
                        continue; 
                    if (grid[px][py] >= grid[j][i])
                        continue;

                    dp[j][i] = max(dp[j][i], dp[px][py] + 1);
                    
                }
                ans = max(dp[j][i],ans);
            }
        }


        return ans;
    }
};
  • 记忆化搜索
cpp 复制代码
class Solution {
public:
    struct Dir {
        constexpr static int dir[][2] = {
            {-1,1},{0,1},{1,1}
        };
    };

    int dfs(int i, int j,
    vector<vector<int>> &mem, const vector<vector<int>> &grid)
    {
        int m = mem.size();
        int n = mem[0].size();

        if (mem[i][j] != -1)
            return  mem[i][j];

        int ans = 0;

        for (auto c:Dir::dir) {
            int nx = i + c[0];
            int ny = j + c[1];

            if ( nx < 0 || nx > m - 1 || ny < 0 || ny > n - 1)
                continue;
            if (grid[i][j] >=grid[nx][ny])
                continue;
            
            int t = dfs(nx,ny, mem, grid);
            ans = max(ans, 1 + t);
        }

        return mem[i][j] = ans;
    }

    int maxMoves(vector<vector<int>>& grid) {
        
        int ans = 0;

        int h = grid.size();
        int w = grid[0].size();
        vector<vector<int>> mem(h, vector<int>(w, -1));


        for (int i = 0;i < h; ++i) {
            ans = max(dfs(i, 0, mem, grid), ans);
        }

        return ans;
    }
};
相关推荐
彧azz18 小时前
算法设计与分析:贪心与动态规划
数据结构·学习·算法·贪心算法·动态规划
俗人六哥AI企业获客盈利系统21 小时前
知识库才是AI落地的分水岭
人工智能·线性代数·矩阵·自动化
微三云 - 廖会灵 (私域系统开发)2 天前
私域电商多端商城系统架构实践:小程序 / APP / H5 一套后端如何落地
矩阵·重构·零售
Logic1012 天前
C语言/数据结构动态规划题解:Kadane算法求最大子数组和——O(n)时间O(1)空间
c语言·数据结构·动态规划·贪心·时间复杂度·算法题·最大子数组和
微三云 - 廖会灵 (私域系统开发)2 天前
多端商城统一账号体系设计实践:小程序 / APP / H5 登录打通与账号合并
矩阵·重构·自动化·零售
梦帮科技3 天前
AI 音乐产品的发布工程:验证门、数据发布、回滚与生产运维纪律
数据结构·数据库·架构·node.js·音视频·动态规划·推荐算法
语戚3 天前
力扣 1621. 大小为K的不重叠线段的数目:动态规划(Java 实现)
java·算法·leetcode·动态规划·力扣·dp
青山木3 天前
Hot 100 --- 最长有效括号
java·数据结构·算法·leetcode·动态规划
这料鬼有毒3 天前
二刷hot100-1143.最长公共子序列
算法·leetcode·动态规划
Tisfy3 天前
LeetCode 1477.找两个和为目标值且不重叠的子数组:滑动窗口 + 记录前值(动态规划)
动态规划·题解·dp·滑动窗口