Talentd
FleetCode
Make and follow sheets.Sign in

Maximum Amount of Money Robot Can Earn solution and explanation

MediumArrayDynamic ProgrammingMatrix6 min read47.9% acceptanceUpdated 24 Mar 2026
Maximum Amount of Money Robot Can Earn | Simple Straight Forward | Leetcode 3418 | codestorywithMIKcodestorywithMIK · 15:52 · 10K viewsWatch on YouTube
9 more videos on this problem
  1. Maximum Amount of Money Robot Can Earn | Simple Straight Forward | Leetcode 3418 | codestorywithMIKcodestorywithMIK · 15:52 · 10K views
  2. 3418. Maximum Amount of Money Robot Can Earn | DP on Grids | Top Down ApproachAryan Mittal · 18:51 · 3K views
  3. Daily Leetcode #2193: Apr 02, 2026 - 3418. Maximum Amount of Money Robot Can EarnProgramming Live with Larry · 10:47 · 658 views
  4. Maximum Amount of Money Robot can Earn | Leetcode 3418 | Java | Hindi | Daily LeetcodeKernel Queen 👑 · 15:19 · 644 views
  5. Leetcode | 3418 Maximum Amount of Money Robot Can Earn | Java | Recursion | Memoization | WeeklyCakot Coding · 26:22 · 518 views
  6. leetcode 3418 | Maximum Amount of Money Robot Can Earn | Dynamic Programming | Leetcode POTD | DSACode With Vick · 24:06 · 466 views
  7. 3418. Maximum Amount of Money Robot Can Earn (Leetcode Medium)Programming Live with Larry · 7:04 · 452 views
  8. Leetcode 3418 | Maximum Amount of Money Robot Can Earn | Weekly Contest 432Road To FAANG · 9:56 · 405 views
  9. Maximum Amount of Money Robot Can Earn | LeetCode 3418 - Pythonimpoldev · 19:18 · 296 views
  10. Maximum Amount of Money Robot Can Earn | LeetCode 3418 | DP | Java Code | Developer CoderDeveloper Coder · 17:12 · 186 views

The problem

You are given an m x n grid. A robot starts at the top-left corner of the grid (0, 0) and wants to reach the bottom-right corner (m - 1, n - 1). The robot can move either right or down at any point in time.

The grid contains a value coins[i][j] in each cell:

  • If coins[i][j] >= 0, the robot gains that many coins.
  • If coins[i][j] < 0, the robot encounters a robber, and the robber steals the absolute value of coins[i][j] coins.

The robot has a special ability to neutralize robbers in at most 2 cells on its path, preventing them from stealing coins in those cells.

Note: The robot's total coins can be negative.

Return the maximum profit the robot can gain on the route.

Example 1:

Input: coins = [[0,1,-1],[1,-2,3],[2,-3,4]]

Output: 8

Explanation:

An optimal path for maximum coins is:

  1. Start at (0, 0) with 0 coins (total coins = 0).
  2. Move to (0, 1), gaining 1 coin (total coins = 0 + 1 = 1).
  3. Move to (1, 1), where there's a robber stealing 2 coins. The robot uses one neutralization here, avoiding the robbery (total coins = 1).
  4. Move to (1, 2), gaining 3 coins (total coins = 1 + 3 = 4).
  5. Move to (2, 2), gaining 4 coins (total coins = 4 + 4 = 8).

Example 2:

Input: coins = [[10,10,10],[10,10,10]]

Output: 40

Explanation:

An optimal path for maximum coins is:

  1. Start at (0, 0) with 10 coins (total coins = 10).
  2. Move to (0, 1), gaining 10 coins (total coins = 10 + 10 = 20).
  3. Move to (0, 2), gaining another 10 coins (total coins = 20 + 10 = 30).
  4. Move to (1, 2), gaining the final 10 coins (total coins = 30 + 10 = 40).

Constraints:

  • m == coins.length
  • n == coins[i].length
  • 1 <= m, n <= 500
  • -1000 <= coins[i][j] <= 1000

Approach overview

Problem Overview: You are given a grid where each cell represents money gained or lost when the robot enters it. The robot starts at the top-left and must reach the bottom-right moving only right or down. Some cells contain robbers (negative values). The robot can neutralize up to two robbers, preventing the loss. The goal is to compute the maximum amount of money the robot can collect along a valid path.

Approach 1: Brute Force DFS (Exponential Time)

Explore every possible path from (0,0) to (m-1,n-1) using depth‑first search. At each cell you decide whether to move right or down. If the value is negative and you still have robber neutralizations left, branch into two choices: take the loss or neutralize it. This generates up to three states per cell and quickly explodes in size. Time complexity is roughly O(2^(m+n)) in the worst case with O(m+n) recursion space, which is impractical for larger grids but useful to reason about the state transitions.

Approach 2: Memoized Search / Top-Down DP (O(m * n * 3))

The key observation is that many DFS states repeat. The robot's future earnings depend only on three values: the current row, the current column, and how many robber neutralizations remain. Cache results using a memo table dp[row][col][k], where k ranges from 0 to 2. From each state, recursively compute the best value from moving right or down. When the current cell contains a negative value and k > 0, you can either accept the loss or neutralize the robber and treat the cell value as zero. Store the maximum result in the memo table so the same state never recomputes.

This transforms the exponential search into a bounded dynamic programming problem. Each cell is evaluated for three possible neutralization states, producing O(m * n * 3) time complexity and the same O(m * n * 3) space complexity for memoization. The approach fits naturally with recursion and memo caching in languages like Python, Java, C++, Go, or TypeScript.

The solution models a classic grid path optimization problem from dynamic programming, extended with an extra decision dimension. Thinking of the grid as a state graph helps: each state branches to two neighbors while tracking remaining power-ups. This pattern appears in many matrix path problems and constrained optimization problems on arrays.

Recommended for interviews: Memoized DFS (top-down DP). Interviewers expect you to identify overlapping subproblems and introduce a state like (row, col, remainingNeutralizations). Explaining the brute-force recursion first demonstrates understanding of the path choices, then adding memoization shows strong dynamic programming instincts.

Solution

We design a function dfs(i, j, k), which represents the maximum amount of coins the robot can collect starting from (i, j) with k conversion opportunities left. The robot can only move right or down, so the value of dfs(i, j, k) depends only on dfs(i + 1, j, k) and dfs(i, j + 1, k).

  • If i geq m or j geq n, it means the robot has moved out of the grid, so we return a very small value.
  • If i = m - 1 and j = n - 1, it means the robot has reached the bottom-right corner of the grid. If k > 0, the robot can choose to convert the bandit at the current position, so we return max(0, coins[i][j]). If k = 0, the robot cannot convert the bandit at the current position, so we return coins[i][j].
  • If coins[i][j] < 0, it means there is a bandit at the current position. If k > 0, the robot can choose to convert the bandit at the current position, so we return coins[i][j] + max(dfs(i + 1, j, k), dfs(i, j + 1, k)). If k = 0, the robot cannot convert the bandit at the current position, so we return coins[i][j] + max(dfs(i + 1, j, k), dfs(i, j + 1, k)).

Based on the above analysis, we can write the code for memoized search.

The time complexity is O(m times n times k), and the space complexity is O(m times n times k). Here, m and n are the number of rows and columns of the 2D array coins, and k is the number of conversion opportunities, which is 3 in this problem.

class Solution:
    def maximumAmount(self, coins: List[List[int]]) -> int:
        @cache
        def dfs(i: int, j: int, k: int) -> int:
            if i >= m or j >= n:
                return -inf
            if i == m - 1 and j == n - 1:
                return max(coins[i][j], 0) if k else coins[i][j]
            ans = coins[i][j] + max(dfs(i + 1, j, k), dfs(i, j + 1, k))
            if coins[i][j] < 0 and k:
                ans = max(ans, dfs(i + 1, j, k - 1), dfs(i, j + 1, k - 1))
            return ans

        m, n = len(coins), len(coins[0])
        return dfs(0, 0, 2)
class Solution {
    private Integer[][][] f;
    private int[][] coins;
    private int m;
    private int n;

    public int maximumAmount(int[][] coins) {
        m = coins.length;
        n = coins[0].length;
        this.coins = coins;
        f = new Integer[m][n][3];
        return dfs(0, 0, 2);
    }

    private int dfs(int i, int j, int k) {
        if (i >= m || j >= n) {
            return Integer.MIN_VALUE / 2;
        }
        if (f[i][j][k] != null) {
            return f[i][j][k];
        }
        if (i == m - 1 && j == n - 1) {
            return k > 0 ? Math.max(0, coins[i][j]) : coins[i][j];
        }
        int ans = coins[i][j] + Math.max(dfs(i + 1, j, k), dfs(i, j + 1, k));
        if (coins[i][j] < 0 && k > 0) {
            ans = Math.max(ans, Math.max(dfs(i + 1, j, k - 1), dfs(i, j + 1, k - 1)));
        }
        return f[i][j][k] = ans;
    }
}
class Solution {
public:
    int maximumAmount(vector<vector<int>>& coins) {
        int m = coins.size(), n = coins[0].size();
        vector<vector<vector<int>>> f(m, vector<vector<int>>(n, vector<int>(3, -1)));
        auto dfs = [&](this auto&& dfs, int i, int j, int k) -> int {
            if (i >= m || j >= n) {
                return INT_MIN / 2;
            }
            if (f[i][j][k] != -1) {
                return f[i][j][k];
            }
            if (i == m - 1 && j == n - 1) {
                return k > 0 ? max(0, coins[i][j]) : coins[i][j];
            }
            int ans = coins[i][j] + max(dfs(i + 1, j, k), dfs(i, j + 1, k));
            if (coins[i][j] < 0 && k > 0) {
                ans = max({ans, dfs(i + 1, j, k - 1), dfs(i, j + 1, k - 1)});
            }
            return f[i][j][k] = ans;
        };
        return dfs(0, 0, 2);
    }
};
function maximumAmount(coins: number[][]): number {
    const [m, n] = [coins.length, coins[0].length];
    const f = Array.from({ length: m }, () =>
        Array.from({ length: n }, () => Array(3).fill(-Infinity)),
    );
    const dfs = (i: number, j: number, k: number): number => {
        if (i >= m || j >= n) {
            return -Infinity;
        }
        if (f[i][j][k] !== -Infinity) {
            return f[i][j][k];
        }
        if (i === m - 1 && j === n - 1) {
            return k > 0 ? Math.max(0, coins[i][j]) : coins[i][j];
        }
        let ans = coins[i][j] + Math.max(dfs(i + 1, j, k), dfs(i, j + 1, k));
        if (coins[i][j] < 0 && k > 0) {
            ans = Math.max(ans, dfs(i + 1, j, k - 1), dfs(i, j + 1, k - 1));
        }
        return (f[i][j][k] = ans);
    };
    return dfs(0, 0, 2);
}
func maximumAmount(coins [][]int) int {
	m, n := len(coins), len(coins[0])
	f := make([][][]int, m)
	for i := range f {
		f[i] = make([][]int, n)
		for j := range f[i] {
			f[i][j] = make([]int, 3)
			for k := range f[i][j] {
				f[i][j][k] = math.MinInt32
			}
		}
	}
	var dfs func(i, j, k int) int
	dfs = func(i, j, k int) int {
		if i >= m || j >= n {
			return math.MinInt32 / 2
		}
		if f[i][j][k] != math.MinInt32 {
			return f[i][j][k]
		}
		if i == m-1 && j == n-1 {
			if k > 0 {
				return max(0, coins[i][j])
			}
			return coins[i][j]
		}
		ans := coins[i][j] + max(dfs(i+1, j, k), dfs(i, j+1, k))
		if coins[i][j] < 0 && k > 0 {
			ans = max(ans, max(dfs(i+1, j, k-1), dfs(i, j+1, k-1)))
		}
		f[i][j][k] = ans
		return ans
	}
	return dfs(0, 0, 2)
}
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Brute Force DFSO(2^(m+n))O(m+n)Conceptual baseline to understand path exploration and decision branching
Memoized Search (Top-Down DP)O(m * n * 3)O(m * n * 3)Optimal solution for grid path problems with limited special actions
Bottom-Up DP (3D Table)O(m * n * 3)O(m * n * 3)Iterative alternative when recursion depth or stack limits are a concern

Frequently asked questions

Is Maximum Amount of Money Robot Can Earn easy or hard?

The problem is rated Medium because the grid traversal itself is simple but the additional robber-neutralization constraint introduces another DP dimension. Recognizing the correct state representation and caching strategy is the main challenge.

Maximum Amount of Money Robot Can Earn Python/Java solution

Implement a DFS function with memoization where the state is (row, col, remainingNeutralizations). At each step compute the best result from moving right or down and decide whether to neutralize a robber if the cell value is negative. Cache results in a dictionary or 3D array. The same logic translates directly to Python, Java, C++, Go, and TypeScript.

How to solve Maximum Amount of Money Robot Can Earn in O(m*n)?

Model the problem as dynamic programming with state (row, col, k) where k is the number of robber neutralizations remaining. Use memoized DFS or a 3D DP table to compute the best value from each cell while moving right or down. Since k only has three values (0–2), the total states become m * n * 3, which simplifies to linear time relative to the grid size.

What is the best approach for Maximum Amount of Money Robot Can Earn?

The most effective approach is memoized depth-first search (top-down dynamic programming). Define a DP state (row, col, remainingNeutralizations) and cache results to avoid recomputation. Each state explores moving right or down while optionally neutralizing a robber. This reduces the complexity to O(m * n * 3).

Is Maximum Amount of Money Robot Can Earn asked at Google/Amazon/Meta?

Problems combining grid traversal with dynamic programming states appear frequently in interviews at companies like Amazon, Google, and Meta. Variants often involve path optimization with constraints such as limited skips, power-ups, or obstacle removals. This problem follows the same DP state expansion pattern.

What data structure is used in Maximum Amount of Money Robot Can Earn?

The solution mainly uses a 3D dynamic programming cache or memoization table indexed by row, column, and remaining neutralizations. The grid itself is stored as a matrix (2D array), and recursion or iteration explores neighbors. The memo table prevents recomputing identical states.

What is the time complexity of Maximum Amount of Money Robot Can Earn?

The optimal dynamic programming solution runs in O(m * n * 3) time, where m and n are grid dimensions and 3 represents the possible counts of remaining robber neutralizations (0, 1, or 2). Each state is computed once and checks at most two transitions. Space complexity is also O(m * n * 3) for memoization.

Comments

Now write it yourselfClose this page and solve Maximum Amount of Money Robot Can Earn in the editor, without looking.
Practise Maximum Amount of Money Robot Can Earn