1. Recursive Dual DFS
Intuition
Recursively advance both travelers right or down simultaneously through all 4 branches.
Algorithm
- Define
solve(r1, c1, r2). c2 = r1 + c1 - r2.- If out of bounds or thorn (-1) at either position, return -\infty.
- If both reach
(n-1, n-1), returngrid[n-1][n-1]. - Cherries gained =
(r1 == r2) ? grid[r1][c1] : grid[r1][c1] + grid[r2][c2]. - Branch 4 ways: (r1+1, c1, r2+1), (r1+1, c1, r2), (r1, c1+1, r2+1), (r1, c1+1, r2).
- Return
cherries + max(all 4 branches).
#include <iostream>#include <vector>#include <algorithm> using namespace std; class Solution { int solve(int r1, int c1, int r2, int n, const vector<vector<int>>& grid) { int c2 = r1 + c1 - r2; if (r1 >= n || c1 >= n || r2 >= n || c2 >= n || grid[r1][c1] == -1 || grid[r2][c2] == -1) { return -1e9; } if (r1 == n - 1 && c1 == n - 1) return grid[r1][c1]; int cherries = (r1 == r2) ? grid[r1][c1] : grid[r1][c1] + grid[r2][c2]; int bestNext = max({ solve(r1 + 1, c1, r2 + 1, n, grid), // Down, Down solve(r1 + 1, c1, r2, n, grid), // Down, Right solve(r1, c1 + 1, r2 + 1, n, grid), // Right, Down solve(r1, c1 + 1, r2, n, grid) // Right, Right }); return cherries + bestNext; }public: int cherryPickup(vector<vector<int>>& grid) { int ans = solve(0, 0, 0, grid.size(), grid); return max(0, ans); }}; int main() { Solution sol; vector<vector<int>> grid = {{0, 1, -1}, {1, 0, -1}, {1, 1, 1}}; cout << "Max Cherries: " << sol.cherryPickup(grid) << endl; return 0;}Time & Space Complexity
- Time complexity:
O(4^(2n)) - Space complexity:
O(n) call stack