<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:
    def minFallingPathSum(self, matrix: List[List[int]]) -> int:
        
        m = len(matrix)
        n = len(matrix[0])
        
        def dp(row,col):
            
            if row >= m or row < 0  or col >= n or col < 0:
                return inf
            
            if row == 0:
                return matrix[row][col]
            
            if (row,col) in memo:
                return memo[(row,col)]
            
            left = dp(row-1, col + 1)
            right = dp(row-1, col - 1)
            center = dp(row-1,col)
            
            ans = min(left, right, center) + matrix[row][col]
            
            memo[(row,col)] = ans
            return ans
        
        ans = inf
        for col in range(n-1,-1,-1):
            memo = {}
            ans = min(ans,dp(m-1,col))
            
        return ans

        # dp = [[inf] * (n+1) for _ in range(m+1)]


        # for row in range(m):
        #     for col in range(n):

        #         # base case continuation, skip further ops
        #         if row == 0:
        #             dp[row][col] = matrix[row][col]
        #             continue
                
        #         ans = inf

        #         left = dp[row-1][col + 1]
        #         right = dp[row-1][col - 1]
        #         center = dp[row-1][col]
                
        #         ans = min(left, right, center) + matrix[row][col]
                
        #         dp[row][col] = ans


        # res = inf
        # for start in range(n): 
        #     res = min(res,dp[m-1][start])

        # return res
            
        
23200