<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:
        n,m=len(matrix),len(matrix[0])
        def solve(i,j,dp):
            if j<0 or j>=m:
                return 1e9
            elif i==n-1:
                dp[i][j]=matrix[i][j]
                return matrix[i][j]
            elif dp[i][j]!=-1:
                return dp[i][j]
            # up
            up=matrix[i][j]+solve(i+1,j,dp)
            # down left

            dl=matrix[i][j]+solve(i+1,j-1,dp)
            # down right
            dr=matrix[i][j]+solve(i+1,j+1,dp)

            dp[i][j]=min(up,dl,dr)
            return dp[i][j]

        
        q=[]
        dp=[[0]*m for _ in range(n)]
        dp[n-1]=matrix[n-1]

        for i in range(n-2,-1,-1):
            for j in range(m-1,-1,-1):
                # up
                up=matrix[i][j]+dp[i+1][j]
                # down left
                if j>0:
                    dl=matrix[i][j]+dp[i+1][j-1]
                else:
                    dl=1e9
                # down right
                if j+1<m:
                    dr=matrix[i][j]+dp[i+1][j+1]
                else:
                    dr=1e9
                dp[i][j]=min(up,min(dl,dr))
    
        return min(dp[0])


        
18500