Cherry Pickup
In a N x N grid representing a field of cherries, each cell is one of three possible integers.
0 means the cell is empty, so you can pass through;
1 means the cell contains a cherry, that you can pick up and pass through;
-1 means the cell contains a thorn that blocks your way.
Your task is to collect maximum number of cherries possible by following the rules below:
Starting at the position (0, 0) and reaching (N-1, N-1) by moving right or down through valid path cells (cells with value 0 or 1);
After reaching (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells;
When passing through a path cell containing a cherry, you pick it up and the cell becomes an empty cell (0);
If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected.
Example 1:
Input: grid =
[[0, 1, -1],
[1, 0, -1],
[1, 1, 1]]
Output: 5
Explanation:
The player started at (0, 0) and went down, down, right right to reach (2, 2).
4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]].
Then, the player went left, up, up, left to return home, picking up one more cherry.
The total number of cherries picked up is 5, and this is the maximum possible.Note:
gridis anNbyN2D array, with1 <= N <= 50.Each
grid[i][j]is an integer in the set{-1, 0, 1}.It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1.
class Solution {
// Take 2 persons starting from top-left together.
// Now we can easily see that a state is defined by 4 variables:
// R1, C1, R2, C2
// But if they start from same position, we can say that they will be
// at T manhattan distance from (0, 0).
// The 2 points will follow this equation: R + C = T
// Time Complexity -> O(N^3)
// Space Complexity -> O(N^3)
Integer[][][] dp;
public int cherryPickup(int[][] grid) {
int n = grid.length;
dp = new Integer[n][n][2 * n];
int ans = helper(grid, 0, 0, 0);
return ans == Integer.MIN_VALUE ? 0 : ans;
}
int[][] options = { { 1, 0 }, { 0, 1 }, { 0, 0 }, { 1, 1 } };
public int helper(int[][] grid, int R1, int R2, int T) {
int C1 = T - R1, C2 = T - R2, n = grid.length;
if (C1 >= n || C2 >= n || R1 >= n || R2 >= n || grid[R1][C1] == -1 || grid[R2][C2] == -1)
return Integer.MIN_VALUE;
// At this point it is guaranteed, that both points will be at (n-1, n-1)
if (R1 == n - 1 && C1 == n - 1)
return grid[R1][C1];
if (dp[R1][R2][T] != null)
return dp[R1][R2][T];
int ans = Integer.MIN_VALUE;
for (int[] option : options)
ans = Math.max(ans, helper(grid, R1 + option[0], R2 + option[1], T + 1));
if (ans != Integer.MIN_VALUE) {
ans += grid[R1][C1];
if (R1 != R2 || C1 != C2)
ans += grid[R2][C2];
}
dp[R1][R2][T] = ans;
return ans;
}
}Last updated