Both Recursive and DP Solution
IntuitionApproachComplexity
Time complexity:

Space complexity:
Code
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->

# Approach
<!-- Describe your approach to solving the problem. -->

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

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

# Code
```java []
class Solution {
    private int Traverse(int[][] coin, int[][][] dp, int i, int j, int robber){
        if(i < 0 || j<0){
            return Integer.MIN_VALUE;
        }

        if(i == 0 && j == 0){
            if(coin[i][j] < 0 && robber > 0){
                return 0;
            }else{
                return coin[i][j];
            }
        }

        if(dp[i][j][robber] != Integer.MIN_VALUE)return dp[i][j][robber];

        if(coin[i][j] < 0 && robber > 0){
            return dp[i][j][robber] = Math.max(Traverse(coin, dp, i-1, j, robber-1), Math.max(Traverse(coin, dp, i, j-1, robber-1), coin[i][j] + Math.max(Traverse(coin, dp, i-1, j, robber), Traverse(coin, dp,  i, j - 1, robber))));
        }else{
            return dp[i][j][robber] = coin[i][j] + Math.max( Traverse(coin, dp, i-1,j,robber),Traverse(coin, dp, i,j-1,robber));
        }
    }

    private int recursiveTraverse(int[][] coin, int i, int j, int robber){
        if(i < 0 || j<0){
            return Integer.MIN_VALUE;
        }
        
        if(i == 0 && j == 0){
            if(coin[i][j] < 0 && robber > 0){
                return 0;
            }else{
                return coin[i][j];
            }
        }

        if(coin[i][j] < 0 && robber > 0){
            return Math.max(recursiveTraverse(coin, i-1, j, robber-1), Math.max(recursiveTraverse(coin, i, j-1, robber-1), coin[i][j] + Math.max(recursiveTraverse(coin,i-1, j, robber), recursiveTraverse(coin, i, j - 1, robber))));
        }else{
            return coin[i][j] + Math.max( recursiveTraverse(coin,i-1,j,robber),recursiveTraverse(coin,i,j-1,robber));
        }
    }

    public int maximumAmount(int[][] coins) {
        int m = coins.length;
        int n = coins[0].length;

        if(m == 1 && n == 1){
            return Math.max(0, coins[0][0]);
        }
        
        int[][][] dp = new int[m][n][3];

        for(int i=0; i<m; i++){
            for(int j = 0; j<n; j++){
                for(int k = 0; k<3; k++){
                    dp[i][j][k] = Integer.MIN_VALUE;
                }
            }
        }
        
        Traverse(coins,dp,m-1,n-1,2);
        int max_coins = Integer.MIN_VALUE;
        for(int i=0; i<3; i++)max_coins = Math.max(max_coins, dp[m-1][n-1][i]);
        return max_coins == Integer.MIN_VALUE ? 0 : max_coins;
    }
}
```
['Java']