<p>Given an <code>n x n</code> array of integers <code>matrix</code>, return <em>the <strong>minimum sum</strong> of any <strong>falling path</strong> through</em> <code>matrix</code>.</p>

<p>A <strong>falling path</strong> starts at any element in the first row and chooses the element in the next row that is either directly below or diagonally left/right. Specifically, the next element from position <code>(row, col)</code> will be <code>(row + 1, col - 1)</code>, <code>(row + 1, col)</code>, or <code>(row + 1, col + 1)</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/11/03/failing1-grid.jpg" style="width: 499px; height: 500px;" />
<pre>
<strong>Input:</strong> matrix = [[2,1,3],[6,5,4],[7,8,9]]
<strong>Output:</strong> 13
<strong>Explanation:</strong> There are two falling paths with a minimum sum as shown.
</pre>

<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/11/03/failing2-grid.jpg" style="width: 164px; height: 365px;" />
<pre>
<strong>Input:</strong> matrix = [[-19,57],[-40,-5]]
<strong>Output:</strong> -59
<strong>Explanation:</strong> The falling path with a minimum sum is shown.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>n == matrix.length == matrix[i].length</code></li>
	<li><code>1 &lt;= n &lt;= 100</code></li>
	<li><code>-100 &lt;= matrix[i][j] &lt;= 100</code></li>
</ul>

class Solution {
public:
    int solve(vector<vector<int>> &matrix, int col, int row, vector<vector<int>> &dp) {
        if (row >= matrix.size())
            return 0;
        if (dp[row][col] != -1)
            return dp[row][col];

        int op1 = 1e9, op2 = 1e9, op3 = 1e9;
        if (col-1 >= 0)
            op1 = solve(matrix, col-1, row+1, dp);
        
        op2 = solve(matrix, col, row+1, dp);

        if (col+1 < matrix[0].size())
            op3 = solve(matrix, col+1, row+1, dp);

        return dp[row][col] = min(op1, min(op2, op3)) + matrix[row][col];
    }

    int solveTab(vector<vector<int>> &matrix) {
        int n = matrix.size();
        int m = matrix[0].size();
        vector<vector<int>> dp(n+1, vector<int>(m+1, 0));

        for (int row = n-1; row >= 0; row--) {
            for (int col = m - 1; col >= 0; col--) {

                int op1 = 1e9, op2 = 1e9, op3 = 1e9;
                if (col-1 >= 0)
                    op1 = dp[row+1][col-1];
                
                op2 = dp[row+1][col];

                if (col+1 < matrix[0].size())
                    op3 = dp[row+1][col+1];

                dp[row][col] = min(op1, min(op2, op3)) + matrix[row][col];
            }
        }
        int mini = INT_MAX;
        for (int i = 0; i < m; i++) {
            mini = min(mini, dp[0][i]);
        }
        return mini;
    }

    int minFallingPathSum(vector<vector<int>>& matrix) {
        return solveTab(matrix);
    }
};
14100