class Solution {
public:
int cherryPickup(vector<vector<int>>& grid) {
}
};
1463. 摘樱桃 II
给你一个 rows x cols
的矩阵 grid
来表示一块樱桃地。 grid
中每个格子的数字表示你能获得的樱桃数目。
你有两个机器人帮你收集樱桃,机器人 1 从左上角格子 (0,0)
出发,机器人 2 从右上角格子 (0, cols-1)
出发。
请你按照如下规则,返回两个机器人能收集的最多樱桃数目:
(i,j)
出发,机器人可以移动到格子 (i+1, j-1)
,(i+1, j)
或者 (i+1, j+1)
。grid
外面。grid
最底下一行。
示例 1:
输入:grid = [[3,1,1],[2,5,1],[1,5,5],[2,1,1]] 输出:24 解释:机器人 1 和机器人 2 的路径在上图中分别用绿色和蓝色表示。 机器人 1 摘的樱桃数目为 (3 + 2 + 5 + 2) = 12 。 机器人 2 摘的樱桃数目为 (1 + 5 + 5 + 1) = 12 。 樱桃总数为: 12 + 12 = 24 。
示例 2:
输入:grid = [[1,0,0,0,0,0,1],[2,0,0,0,0,3,0],[2,0,9,0,0,0,0],[0,3,0,5,4,0,0],[1,0,2,3,0,0,6]] 输出:28 解释:机器人 1 和机器人 2 的路径在上图中分别用绿色和蓝色表示。 机器人 1 摘的樱桃数目为 (1 + 9 + 5 + 2) = 17 。 机器人 2 摘的樱桃数目为 (1 + 3 + 4 + 3) = 11 。 樱桃总数为: 17 + 11 = 28 。
示例 3:
输入:grid = [[1,0,0,3],[0,0,0,3],[0,0,3,3],[9,0,3,3]] 输出:22
示例 4:
输入:grid = [[1,1],[1,1]] 输出:4
提示:
rows == grid.length
cols == grid[i].length
2 <= rows, cols <= 70
0 <= grid[i][j] <= 100
原站题解
rust 解法, 执行用时: 17 ms, 内存消耗: 2.2 MB, 提交时间: 2024-05-07 07:36:05
impl Solution { pub fn cherry_pickup(grid: Vec<Vec<i32>>) -> i32 { let m = grid.len(); let n = grid[0].len(); let mut f = vec![vec![-1; n]; n]; let mut g = vec![vec![-1; n]; n]; f[0][n - 1] = grid[0][0] + grid[0][n - 1]; for i in 1..m { for j1 in 0..n { for j2 in 0..n { let mut best = -1; for dj1 in -1..=1 { for dj2 in -1..=1 { let dj1 = j1 as i32 + dj1; let dj2 = j2 as i32 + dj2; if dj1 >= 0 && dj1 < n as i32 && dj2 >= 0 && dj2 < n as i32 && f[dj1 as usize][dj2 as usize] != -1 { best = best.max(f[dj1 as usize][dj2 as usize] + if j1 == j2 { grid[i][j1] } else { grid[i][j1] + grid[i][j2] }); } } } g[j1][j2] = best; } } std::mem::swap(&mut f, &mut g); } let mut ans = 0; for j1 in 0..n { ans = ans.max(*f[j1].iter().max().unwrap_or(&0)); } ans } }
javascript 解法, 执行用时: 106 ms, 内存消耗: 52.4 MB, 提交时间: 2024-05-07 07:35:46
/** * @param {number[][]} grid * @return {number} */ var cherryPickup = function(grid) { const m = grid.length; const n = grid[0].length; let f = Array.from({ length: n }, () => Array(n).fill(-1)); let g = Array.from({ length: n }, () => Array(n).fill(-1)); f[0][n - 1] = grid[0][0] + grid[0][n - 1]; for (let i = 1; i < m; ++i) { for (let j1 = 0; j1 < n; ++j1) { for (let j2 = 0; j2 < n; ++j2) { let best = -1; for (let dj1 = j1 - 1; dj1 <= j1 + 1; ++dj1) { for (let dj2 = j2 - 1; dj2 <= j2 + 1; ++dj2) { if (dj1 >= 0 && dj1 < n && dj2 >= 0 && dj2 < n && f[dj1][dj2] != -1) { best = Math.max(best, f[dj1][dj2] + (j1 == j2 ? grid[i][j1] : grid[i][j1] + grid[i][j2])); } } } g[j1][j2] = best; } } [f, g] = [g, f]; } let ans = 0; for (let j1 = 0; j1 < n; ++j1) { ans = Math.max(ans, Math.max(...f[j1])); } return ans; };
golang 解法, 执行用时: 16 ms, 内存消耗: 6.4 MB, 提交时间: 2023-09-21 23:23:50
func cherryPickup(grid [][]int) int { // f[i][j][k] 表示第i行摘取j,k桃子的最大值 // 令j<k // f[i][j][k] = max(f[i-1][g(j,k)]) + grid[j] + grid[k] n, m := len(grid), len(grid[0]) f := make([]int, m*m) // 当f[i][j] == 0 时表示该位置不可达 f[0*m+m-1] = grid[0][0]+grid[0][m-1] + 1 // +1是防止第一个元素为0,因为0表示不可达,最后结果-1即可 for i := 1; i < n; i++ { p := make([]int, m*m) for j := 0; j < min(i+1, m-1); j++ { for z := max(m-1-i, j+1); z < m; z++ { // 计算[j][z]的可考虑范围 for jj := max(0, j-1); jj <= min(m-1, j+1); jj++ { for zz := max(jj+1, z-1); zz <= min(m-1, z+1); zz++ { if f[jj*m+zz] == 0 { continue } // 这个位置不可达 p[j*m+z] = max(p[j*m+z], f[jj*m+zz]+grid[i][j]+grid[i][z]) } } } } f = p } _max := 0 for i := 0; i < m-1; i++ { for j := i+1; j < m; j++ { _max = max(f[i*m+j], _max) } } return _max-1 // 减去添加的那个桃子 } func max(a, b int) int { if a > b { return a }; return b } func min(a, b int) int { if a < b { return a }; return b }
python3 解法, 执行用时: 1004 ms, 内存消耗: 55.5 MB, 提交时间: 2023-09-21 23:22:19
class Solution: def cherryPickup(self, grid: List[List[int]]) -> int: m, n = len(grid), len(grid[0]) def getValue(i, j1, j2): return grid[i][j1] + grid[i][j2] if j1 != j2 else grid[i][j1] @lru_cache(None) def dfs(i, j1, j2): if i == m - 1: return getValue(i, j1, j2) best = 0 for dj1 in [j1 - 1, j1, j1 + 1]: for dj2 in [j2 - 1, j2, j2 + 1]: if 0 <= dj1 < n and 0 <= dj2 < n: best = max(best, dfs(i + 1, dj1, dj2)) return best + getValue(i, j1, j2) return dfs(0, 0, n - 1)
java 解法, 执行用时: 30 ms, 内存消耗: 41.8 MB, 提交时间: 2023-09-21 23:21:22
class Solution { public int cherryPickup(int[][] grid) { int m = grid.length; int n = grid[0].length; int[][] f = new int[n][n]; int[][] g = new int[n][n]; for (int i = 0; i < n; i++) { Arrays.fill(f[i], -1); Arrays.fill(g[i], -1); } f[0][n - 1] = grid[0][0] + grid[0][n - 1]; for (int i = 1; i < m; ++i) { for (int j1 = 0; j1 < n; ++j1) { for (int j2 = 0; j2 < n; ++j2) { int best = -1; for (int dj1 = j1 - 1; dj1 <= j1 + 1; ++dj1) { for (int dj2 = j2 - 1; dj2 <= j2 + 1; ++dj2) { if (dj1 >= 0 && dj1 < n && dj2 >= 0 && dj2 < n && f[dj1][dj2] != -1) { best = Math.max(best, f[dj1][dj2] + (j1 == j2 ? grid[i][j1] : grid[i][j1] + grid[i][j2])); } } } g[j1][j2] = best; } } int[][] temp = f; f = g; g = temp; } int ans = 0; for (int j1 = 0; j1 < n; ++j1) { for (int j2 = 0; j2 < n; ++j2) { ans = Math.max(ans, f[j1][j2]); } } return ans; } }
cpp 解法, 执行用时: 112 ms, 内存消耗: 9.5 MB, 提交时间: 2023-09-21 23:21:05
/** * 设矩阵的长度为 m,宽度为 n,我们用 f[i][j1][j2] 表示当第一个机器人从 (0,0) 走到 (i,j1), * 第二个机器人从 (0,n−1) 走到 (i,j2),最多能收集的樱桃数目。 * */ class Solution { public: int cherryPickup(vector<vector<int>>& grid) { int m = grid.size(); int n = grid[0].size(); vector<vector<int>> f(n, vector<int>(n, -1)), g(n, vector<int>(n, -1)); f[0][n - 1] = grid[0][0] + grid[0][n - 1]; for (int i = 1; i < m; ++i) { for (int j1 = 0; j1 < n; ++j1) { for (int j2 = 0; j2 < n; ++j2) { int best = -1; for (int dj1 = j1 - 1; dj1 <= j1 + 1; ++dj1) { for (int dj2 = j2 - 1; dj2 <= j2 + 1; ++dj2) { if (dj1 >= 0 && dj1 < n && dj2 >= 0 && dj2 < n && f[dj1][dj2] != -1) { best = max(best, f[dj1][dj2] + (j1 == j2 ? grid[i][j1] : grid[i][j1] + grid[i][j2])); } } } g[j1][j2] = best; } } swap(f, g); } int ans = 0; for (int j1 = 0; j1 < n; ++j1) { for (int j2 = 0; j2 < n; ++j2) { ans = max(ans, f[j1][j2]); } } return ans; } };