|
| 1 | +## 741. Cherry Pickup |
| 2 | + |
| 3 | +### Question |
| 4 | +In a N x N grid representing a field of cherries, each cell is one of three possible integers. |
| 5 | +* 0 means the cell is empty, so you can pass through; |
| 6 | +* 1 means the cell contains a cherry, that you can pick up and pass through; |
| 7 | +* -1 means the cell contains a thorn that blocks your way. |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +Your task is to collect maximum number of cherries possible by following the rules below: |
| 12 | +* 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); |
| 13 | +* After reaching (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells; |
| 14 | +* When passing through a path cell containing a cherry, you pick it up and the cell becomes an empty cell (0); |
| 15 | +* If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected. |
| 16 | + |
| 17 | +``` |
| 18 | +Example 1: |
| 19 | +
|
| 20 | +Input: grid = |
| 21 | +[[0, 1, -1], |
| 22 | + [1, 0, -1], |
| 23 | + [1, 1, 1]] |
| 24 | +Output: 5 |
| 25 | +Explanation: |
| 26 | +The player started at (0, 0) and went down, down, right right to reach (2, 2). |
| 27 | +4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]]. |
| 28 | +Then, the player went left, up, up, left to return home, picking up one more cherry. |
| 29 | +The total number of cherries picked up is 5, and this is the maximum possible. |
| 30 | +``` |
| 31 | + |
| 32 | +Note: |
| 33 | +1. grid is an N by N 2D array, with 1 <= N <= 50. |
| 34 | +2. Each grid[i][j] is an integer in the set {-1, 0, 1}. |
| 35 | +3. It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1. |
| 36 | + |
| 37 | +### Solution: |
| 38 | +* Method 1: dp |
| 39 | +  |
| 40 | + * dp[x1][y1][x2]: the max cherry can pick up to (x1, y1), (x2, y2) where y2 = x1 + y1 - x2. This dp means we have 2 people picking cherry from (0, 0) to (N - 1, N - 1). |
| 41 | + * dp[x1][y1][x2] = max(dp(x1 - 1, y1, x2), dp(x1, y1 - 1, x2), dp(x1 - 1, y1, x2 - 1), dp(x1, y1 - 1, x2 - 1)) + grid[x1][y1] + grid[x2][y2]. |
| 42 | + * if both at same position, and current value is 1, only increase once. |
| 43 | + ```Java |
| 44 | + class Solution { |
| 45 | + private int[][][] dp; |
| 46 | + public int cherryPickup(int[][] grid) { |
| 47 | + int height = grid.length, width = grid[0].length; |
| 48 | + dp = new int[height][width][height]; |
| 49 | + for(int i = 0; i < height; i++) |
| 50 | + for(int j = 0; j < width; j++) |
| 51 | + Arrays.fill(dp[i][j], Integer.MIN_VALUE); |
| 52 | + return Math.max(dp(grid, height - 1, width - 1, height - 1), 0); |
| 53 | + } |
| 54 | + private int dp(int[][] grid, int x1, int y1, int x2){ |
| 55 | + int y2 = x1 + y1 - x2; |
| 56 | + if(x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0){ |
| 57 | + return -1; |
| 58 | + } |
| 59 | + if(x1 == 0 && y1 == 0 && x2 == 0){ |
| 60 | + dp[0][0][0] = grid[0][0]; |
| 61 | + return dp[0][0][0]; |
| 62 | + } |
| 63 | + if(dp[x1][y1][x2] != Integer.MIN_VALUE) return dp[x1][y1][x2]; |
| 64 | + if(grid[x1][y1] == -1 || grid[x2][y2] == -1) return -1; |
| 65 | + dp[x1][y1][x2] = Math.max(Math.max(dp(grid, x1 - 1, y1, x2), dp(grid, x1, y1 - 1, x2)), |
| 66 | + Math.max(dp(grid, x1, y1 - 1, x2 - 1), dp(grid, x1 - 1, y1, x2 - 1))); |
| 67 | + if(dp[x1][y1][x2] >= 0){ |
| 68 | + int g1 = grid[x1][y1], g2 = grid[x2][y2]; |
| 69 | + if(g1 >= 0) dp[x1][y1][x2] += g1; |
| 70 | + if(g2 >= 0) dp[x1][y1][x2] += g2; |
| 71 | + if(g1 == g2 && g1 == 1 && x1 == x2 && y1 == y2) |
| 72 | + dp[x1][y1][x2]--; |
| 73 | + } |
| 74 | + return dp[x1][y1][x2]; |
| 75 | + } |
| 76 | + } |
| 77 | + ``` |
| 78 | + |
| 79 | + |
| 80 | +### Reference |
| 81 | +1. [花花酱 LeetCode 741. Cherry Pickup](http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-741-cherry-pickup/) |
0 commit comments