Cherry Pickup

Max cherries on two paths from top-left to bottom-right then back — simulate two simultaneous downward paths in 3D DP.

Hard
Time O(n^3) Space O(n^2)
LeetCode
7 min read
dp grid

Problem#

Grid: 0 empty, 1 cherry, -1 thorn. Walk top-left → bottom-right (right/down) collecting cherries; then bottom-right → top-left (left/up). Pickup any cell once. Max cherries collected.

Hints#

Hint 1
Equivalent to two simultaneous walkers from top-left to bottom-right. After k steps, both are on the anti-diagonal r + c = k.

Approach#

3D DP dp[r1][r2] (with c1 = step - r1, c2 = step - r2). For each step k = 0..2n-2, both walkers are at total Manhattan distance k from origin. Transition: each walker came from “right” or “down” — 4 combinations. If they’re at the same cell, count cherry once.

Solution#

Cherry Pickup
class Solution {
public:
int cherryPickup(vector<vector<int>>& grid) {
int n = grid.size();
vector<vector<int>> dp(n, vector<int>(n, INT_MIN));
dp[0][0] = grid[0][0];
for (int k = 1; k <= 2 * (n - 1); ++k) {
vector<vector<int>> nd(n, vector<int>(n, INT_MIN));
for (int r1 = max(0, k - (n - 1)); r1 <= min(n - 1, k); ++r1) {
for (int r2 = max(0, k - (n - 1)); r2 <= min(n - 1, k); ++r2) {
int c1 = k - r1, c2 = k - r2;
if (grid[r1][c1] == -1 || grid[r2][c2] == -1) continue;
int best = INT_MIN;
for (int dr1 : {0, 1}) for (int dr2 : {0, 1}) {
int pr1 = r1 - dr1, pr2 = r2 - dr2;
if (pr1 < 0 || pr2 < 0) continue;
if (dp[pr1][pr2] != INT_MIN) best = max(best, dp[pr1][pr2]);
}
if (best == INT_MIN) continue;
int add = grid[r1][c1];
if (r1 != r2) add += grid[r2][c2];
nd[r1][r2] = best + add;
}
}
dp = nd;
}
return max(dp[n - 1][n - 1], 0);
}
};

Editorial#

The two-walker reformulation is the key trick — return paths in the original problem map to a second forward walker. Sharing the time k = r + c reduces dimensionality by one (we only need r1, r2; columns follow).

Complexity#

  • Time: O(n³).
  • Space: O(n²).

Concept revision#

Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.