public class Solution { private int[,] PrepareDP(int[][] grid) { int[,] dp = new int[grid.Length, grid.Length]; var y = grid.Length - 1; for (var x = 0; x < grid.Length; ++x) { dp[y, x] = grid[y][x]; } return dp; } private void Compute(int[][] grid, int[,] dp, int y, int x0) { var minimum = int.MaxValue; for (var x = 0; x < grid.Length; ++x) { // need to continue with different column if (x == x0) { continue; } minimum = Math.Min(minimum, dp[y + 1, x]); } dp[y, x0] = grid[y][x0] + minimum; } public int MinFallingPathSum(int[][] grid) { var dp = PrepareDP(grid); for (var y = grid.Length - 2; y >= 0; --y) { for (var x = 0; x < grid.Length; ++x) { Compute(grid, dp, y, x); } } int minFallingPath = int.MaxValue; for (var x = 0; x < grid.Length; ++x) { minFallingPath = Math.Min(minFallingPath, dp[0, x]); } return minFallingPath; } }