# Cherry Pickup in C++

Suppose we have one N x N grid, this is filled with cherries. Each cell has one of the possible integers as follows −

• 0 − Indicates cell is empty, so we can pass through
• 1 − Indicates cell contains a cherry, that we can pick up and pass through
• -1 − Indicates the cell is containing a thorn that blocks the way

We have to collect maximum number of cherries using these few rules −

• Start from position (0, 0) and end at (N-1, N-1) by moving right or down through valid path cells
• After reaching the cell (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells;
• When we are passing through a path cell containing a cherry, we pick it up and the cell becomes an empty cell (the value will be 0);
• If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected.

So, if the input is like −

 0 1 -1 1 0 -1 1 1 1

The output will be 5, as starting from position (0, 0) and went down, down, right, right to reach (2, 2). Here 4 cherries were picked up during this single trip, and the matrix becomes.

 0 1 -1 0 0 -1 0 0 0

Then, the we will go to left, up, up, left to return (0,0), picking up one more cherry. The total number of cherries picked up will be 5.

To solve this, we will follow these steps −

• Define an array dir of size: 2 x 2 := {{1, 0}, {0, 1}}
• INF := 10^9
• Define an array dp of size: 51 x 51 x 51.
• Define a function solve(), this will take r1, c1, c2, one 2D array >& grid,
• n := size of grid, r2 := r1 + c1 - c2, ret := 0
• m := (if n is non-zero, then size of grid[0], otherwise 0)
• if r1 < 0 or c1 < 0 or r2 < 0 or c2 < 0 or r1 >= n or r2 >= n or c1 >= m or c2 >= m, then −
• return -INF
• if grid[r1, c1] is same as -1 or grid[r2, c2] is same as -1, then −
• return -INF
• if r1 is same as r2 and c1 is same as c2 and r1 is same as n - 1 and c1 is same as m - 1, then −
• return grid[r1, c1]
• if dp[r1, c1, c2] is not equal to -1, then −
• return dp[r1, c1, c2]
• ret := ret + grid[r1, c1]
• if r1 is same as r2 and c1 is same as c2, then: do nothing
• Otherwise
• ret := ret + grid[r2, c2]
• temp := -INF
• for initialize k := 0, when k < 2, update (increase k by 1), do −
• temp := maximum of temp and solve(r1 + dir[k, 0], c1 + dir[k, 1], c2 + 1, grid)
• temp := maximum of temp and solve(r1 + dir[k, 0], c1 + dir[k, 1], c2, grid)
• return dp[r1, c1, c2] = ret + temp
• From the main method, do the following −
• Fill dp with -1
• ret := solve(0, 0, 0, grid)
• return maximum of 0 and ret

Let us see the following implementation to get better understanding −

## Example

Live Demo

#include <bits/stdc++.h>
using namespace std;
int dir[2][2] = {{1, 0}, {0, 1}};
const int INF = 1e9;
class Solution {
public:
int dp[51][51][51];
int solve(int r1, int c1, int c2, vector < vector <int> >& grid){
int n = grid.size();
int r2 = r1 + c1 - c2;
int ret = 0;
int m = n? grid[0].size() : 0;
if(r1 < 0 || c1 < 0 || r2 < 0 || c2 < 0 || r1 >= n || r2 >= n || c1 >= m || c2 >= m) return -INF;
if(grid[r1][c1] == -1 || grid[r2][c2] == -1) return -INF;
if(r1 == r2 && c1 == c2 && r1 == n - 1 && c1 == m - 1)return grid[r1][c1];
if(dp[r1][c1][c2] != -1) return dp[r1][c1][c2];
ret += grid[r1][c1];
if(r1 == r2 && c1 == c2){
}else ret += grid[r2][c2];
int temp = -INF;
for(int k = 0; k < 2; k++){
temp = max(temp, solve(r1 + dir[k][0], c1 + dir[k][1], c2 + 1, grid));
temp = max(temp, solve(r1 + dir[k][0], c1 + dir[k][1], c2, grid));
}
return dp[r1][c1][c2] = ret + temp;
}
int cherryPickup(vector<vector<int>>& grid) {
memset(dp, -1, sizeof(dp));
int ret = solve(0, 0, 0, grid);
return max(0, ret);
}
};
main(){
Solution ob;
vector<vector<int>> v = {{0,1,-1},{1,0,-1},{1,1,1}};
cout << (ob.cherryPickup(v));
}

## Input

{{0,1,-1},{1,0,-1},{1,1,1}}

## Output

5

Advertisements