You are given an m x n matrix grid consisting of positive integers.
You can move from a cell in the matrix to any other cell that is either to the bottom or to the right (not necessarily adjacent). The score of a move from a cell with the value c1 to a cell with the value c2 is c2 - c1.
You can start at any cell, and you have to make at least one move.

Input: grid =[[9,5,7,3],[8,9,6,1],[6,7,14,3],[2,5,3,1]]Output: 9Explanation: We start at the cell `(0, 1)`, and we perform the following
moves:
\- Move from the cell `(0, 1)` to `(2, 1)`with a score of `7 - 5 = 2`.\- Move from the cell `(2, 1)` to `(2, 2)`with a score of `14 - 7 = 7`.The total score is`2 + 7 = 9`.

Input: grid =[[4,3,2],[3,2,1]]Output: -1Explanation: We start at the cell `(0, 0)`, and we perform one move:`(0,
0)` to `(0, 1)`. The score is`3 - 4 = -1`.
To maximize the score, for each cell, we want to find the minimum value in the submatrix to its bottom-right (including itself), and then for each cell, check the difference between any cell to its right or below and itself. We can precompute the minimum value for each bottom-right submatrix using DP.
Create a min_suf matrix where min_suf[i][j] is the minimum value in the submatrix starting at (i, j) to the bottom-right corner.
Fill min_suf from bottom-right to top-left.
For each cell (i, j), check all possible moves to the right or below (i.e., any cell (x, y) with x >= i and y >= j), but we only need to check the minimum in the submatrix.
The maximum score is the maximum of min_suf[x][y] - grid[i][j] for all valid moves.
classSolution {
public:int maxScore(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
vector<vector<int>> min_suf(m, vector<int>(n));
for (int i = m-1; i >=0; --i) {
for (int j = n-1; j >=0; --j) {
min_suf[i][j] = grid[i][j];
if (i+1< m) min_suf[i][j] = min(min_suf[i][j], min_suf[i+1][j]);
if (j+1< n) min_suf[i][j] = min(min_suf[i][j], min_suf[i][j+1]);
if (i+1< m && j+1< n) min_suf[i][j] = min(min_suf[i][j], min_suf[i+1][j+1]);
}
}
int ans = INT_MIN;
for (int i =0; i < m; ++i) {
for (int j =0; j < n; ++j) {
if (i+1< m) ans = max(ans, min_suf[i+1][j] - grid[i][j]);
if (j+1< n) ans = max(ans, min_suf[i][j+1] - grid[i][j]);
}
}
return ans;
}
};
classSolution {
publicintmaxScore(int[][] grid) {
int m = grid.length, n = grid[0].length;
int[][] minSuf =newint[m][n];
for (int i = m-1; i >= 0; i--) {
for (int j = n-1; j >= 0; j--) {
minSuf[i][j]= grid[i][j];
if (i+1 < m) minSuf[i][j]= Math.min(minSuf[i][j], minSuf[i+1][j]);
if (j+1 < n) minSuf[i][j]= Math.min(minSuf[i][j], minSuf[i][j+1]);
if (i+1 < m && j+1 < n) minSuf[i][j]= Math.min(minSuf[i][j], minSuf[i+1][j+1]);
}
}
int ans = Integer.MIN_VALUE;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i+1 < m) ans = Math.max(ans, minSuf[i+1][j]- grid[i][j]);
if (j+1 < n) ans = Math.max(ans, minSuf[i][j+1]- grid[i][j]);
}
}
return ans;
}
}
classSolution {
funmaxScore(grid: Array<IntArray>): Int {
val m = grid.size
val n = grid[0].size
val minSuf = Array(m) { IntArray(n) }
for (i in m-1 downTo 0) {
for (j in n-1 downTo 0) {
minSuf[i][j] = grid[i][j]
if (i+1 < m) minSuf[i][j] = minOf(minSuf[i][j], minSuf[i+1][j])
if (j+1 < n) minSuf[i][j] = minOf(minSuf[i][j], minSuf[i][j+1])
if (i+1 < m && j+1 < n) minSuf[i][j] = minOf(minSuf[i][j], minSuf[i+1][j+1])
}
}
var ans = Int.MIN_VALUE
for (i in0 until m) {
for (j in0 until n) {
if (i+1 < m) ans = maxOf(ans, minSuf[i+1][j] - grid[i][j])
if (j+1 < n) ans = maxOf(ans, minSuf[i][j+1] - grid[i][j])
}
}
return ans
}
}
classSolution:
defmaxScore(self, grid: list[list[int]]) -> int:
m, n = len(grid), len(grid[0])
min_suf = [[0]*n for _ in range(m)]
for i in range(m-1, -1, -1):
for j in range(n-1, -1, -1):
min_suf[i][j] = grid[i][j]
if i+1< m:
min_suf[i][j] = min(min_suf[i][j], min_suf[i+1][j])
if j+1< n:
min_suf[i][j] = min(min_suf[i][j], min_suf[i][j+1])
if i+1< m and j+1< n:
min_suf[i][j] = min(min_suf[i][j], min_suf[i+1][j+1])
ans = float('-inf')
for i in range(m):
for j in range(n):
if i+1< m:
ans = max(ans, min_suf[i+1][j] - grid[i][j])
if j+1< n:
ans = max(ans, min_suf[i][j+1] - grid[i][j])
return ans
impl Solution {
pubfnmax_score(grid: Vec<Vec<i32>>) -> i32 {
let m = grid.len();
let n = grid[0].len();
letmut min_suf =vec![vec![0; n]; m];
for i in (0..m).rev() {
for j in (0..n).rev() {
min_suf[i][j] = grid[i][j];
if i+1< m { min_suf[i][j] = min_suf[i][j].min(min_suf[i+1][j]); }
if j+1< n { min_suf[i][j] = min_suf[i][j].min(min_suf[i][j+1]); }
if i+1< m && j+1< n { min_suf[i][j] = min_suf[i][j].min(min_suf[i+1][j+1]); }
}
}
letmut ans =i32::MIN;
for i in0..m {
for j in0..n {
if i+1< m { ans = ans.max(min_suf[i+1][j] - grid[i][j]); }
if j+1< n { ans = ans.max(min_suf[i][j+1] - grid[i][j]); }
}
}
ans
}
}