Problem: Maximum Number of Moves in a Grid

You are given a 0-indexed `m x n` matrix `grid` consisting of positive
integers.

You can start at any cell in the first column of the matrix, and traverse the
grid in the following way:

* From a cell `(row, col)`, you can move to any of the cells: `(row - 1, col + 1)`, `(row, col + 1)` and `(row + 1, col + 1)` such that the value of the cell you move to, should be strictly bigger than the value of the current cell.

Return the maximum number of moves that you can perform.


Python solution:
import math
import itertools
import bisect
import collections
import string
import heapq
import functools
import sortedcontainers
from typing import List, Dict, Tuple, Iterator

class Solution:
  def maxMoves(self, grid: List[List[int]]) -> int:
    m = len(grid)
    n = len(grid[0])
    dp = [[0] * n for _ in range(m)]

    for j in range(n - 2, -1, -1):
      for i in range(m):
        if grid[i][j + 1] > grid[i][j]:
          dp[i][j] = 1 + dp[i][j + 1]
        if i > 0 and grid[i - 1][j + 1] > grid[i][j]:
          dp[i][j] = max(dp[i][j], 1 + dp[i - 1][j + 1])
        if i + 1 < m and grid[i + 1][j + 1] > grid[i][j]:
          dp[i][j] = max(dp[i][j], 1 + dp[i + 1][j + 1])

    return max(dp[i][0] for i in range(m))


Java solution:
class Solution {
  public int maxMoves(int[][] grid) {
    final int m = grid.length;
    final int n = grid[0].length;
    int ans = 0;
    // dp[i][j] := the maximum number of moves you can perform from (i, j)
    int[][] dp = new int[m][n];

    for (int j = n - 2; j >= 0; --j)
      for (int i = 0; i < m; ++i) {
        if (grid[i][j + 1] > grid[i][j])
          dp[i][j] = 1 + dp[i][j + 1];
        if (i > 0 && grid[i - 1][j + 1] > grid[i][j])
          dp[i][j] = Math.max(dp[i][j], 1 + dp[i - 1][j + 1]);
        if (i + 1 < m && grid[i + 1][j + 1] > grid[i][j])
          dp[i][j] = Math.max(dp[i][j], 1 + dp[i + 1][j + 1]);
      }

    for (int i = 0; i < m; ++i)
      ans = Math.max(ans, dp[i][0]);

    return ans;
  }
}


C++ solution:
class Solution {
 public:
  int maxMoves(vector<vector<int>>& grid) {
    const int m = grid.size();
    const int n = grid[0].size();
    int ans = 0;
    // dp[i][j] := the maximum number of moves you can perform from (i, j)
    vector<vector<int>> dp(m, vector<int>(n));

    for (int j = n - 2; j >= 0; --j)
      for (int i = 0; i < m; ++i) {
        if (grid[i][j + 1] > grid[i][j])
          dp[i][j] = 1 + dp[i][j + 1];
        if (i > 0 && grid[i - 1][j + 1] > grid[i][j])
          dp[i][j] = max(dp[i][j], 1 + dp[i - 1][j + 1]);
        if (i + 1 < m && grid[i + 1][j + 1] > grid[i][j])
          dp[i][j] = max(dp[i][j], 1 + dp[i + 1][j + 1]);
      }

    for (int i = 0; i < m; ++i)
      ans = max(ans, dp[i][0]);

    return ans;
  }
};