Java Solution | Easy to Understand | Beats 100% | Clean Code
IntuitionKeep calculating the maximum coins collected by going through the grid ans skip negative coins when allowed.Approachuse a 3D dynamic programming table
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
Keep calculating the maximum coins collected by going through the grid ans skip negative coins when allowed.
# Approach
<!-- Describe your approach to solving the problem. -->
use a 3D dynamic programming table to store the results for each cell and the remaining skips.
# Complexity
- Time complexity: O(m * n * 3)
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: O(m * n * 3)
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```java []
class Solution {
    public int solve(int i, int j, int k, Integer[][][] dp, int[][] coins) {
        if (i == coins.length || j == coins[0].length) {
            return Integer.MIN_VALUE;
        } 
        if (i == coins.length - 1 && j == coins[0].length - 1) {
            if(coins[i][j] < 0 && k < 2){
                return 0;
            }
            return coins[i][j];
        } 
        if (dp[i][j][k] != null) {
            return dp[i][j][k];
        }
        int down = solve(i + 1, j, k, dp, coins); 
        int right = solve(i, j + 1, k, dp, coins); 
        int take = coins[i][j] + Math.max(down, right);

        int not = Integer.MIN_VALUE;
        if (coins[i][j] < 0 && k < 2) {
            int skipDown = solve(i + 1, j, k + 1, dp, coins); 
            int skipRight = solve(i, j + 1, k + 1, dp, coins); 
            not = Math.max(skipDown, skipRight);
        }

        return dp[i][j][k] = Math.max(take, not); 

    }

    public int maximumAmount(int[][] coins) {
        int m = coins.length;
        int n = coins[0].length;
        Integer dp[][][] = new Integer[m][n][3];
        return solve(0, 0, 0, dp, coins);
    }
}

```
['Dynamic Programming', 'Memoization', 'Java']