<p>Given an <code>n x n</code> integer matrix <code>grid</code>, return <em>the minimum sum of a <strong>falling path with non-zero shifts</strong></em>.</p>

<p>A <strong>falling path with non-zero shifts</strong> is a choice of exactly one element from each row of <code>grid</code> such that no two elements chosen in adjacent rows are in the same column.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/08/10/falling-grid.jpg" style="width: 244px; height: 245px;" />
<pre>
<strong>Input:</strong> grid = [[1,2,3],[4,5,6],[7,8,9]]
<strong>Output:</strong> 13
<strong>Explanation:</strong> 
The possible falling paths are:
[1,5,9], [1,5,7], [1,6,7], [1,6,8],
[2,4,8], [2,4,9], [2,6,7], [2,6,8],
[3,4,8], [3,4,9], [3,5,7], [3,5,9]
The falling path with the smallest sum is&nbsp;[1,5,7], so the answer is&nbsp;13.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> grid = [[7]]
<strong>Output:</strong> 7
</pre>

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

<ul>
	<li><code>n == grid.length == grid[i].length</code></li>
	<li><code>1 &lt;= n &lt;= 200</code></li>
	<li><code>-99 &lt;= grid[i][j] &lt;= 99</code></li>
</ul>

class Solution {
public:
    long long solve(int prev, int idx, vector<vector<int>>& grid, int n, int m, vector<vector<long long>>& dp) {
        if (idx == n) {
            return 0;  // Base case: No more rows to process
        }

        // Memoization check
        if (prev != -1 && dp[prev][idx] != LLONG_MAX) {
            return dp[prev][idx];
        }

        long long ans = LLONG_MAX;

        // Traverse all columns for the current row
        for (int i = 0; i < m; i++) {
            if (i != prev) {  // Don't use the previous column in the next row
                long long temp = grid[idx][i] + solve(i, idx + 1, grid, n, m, dp);
                ans = min(ans, temp);  // Minimize the path sum
            }
        }

        // Store result in dp array (only if prev is not -1)
        if (prev != -1) {
            dp[prev][idx] = ans;
        }

        return ans;
    }

    int minFallingPathSum(vector<vector<int>>& grid) {
        int n = grid.size();
        int m = grid[0].size();

        // DP table initialized to LLONG_MAX to signify uncomputed states
        vector<vector<long long>> dp(m, vector<long long>(n, LLONG_MAX));

        // Call the recursive function starting from the first row with no previous column (-1)
        return solve(-1, 0, grid, n, m, dp);
    }
};

19500