Minimum Falling Path

Introduction

 
In this article, we will sove the leetcode problem #931, Minimum Falling Path Sum. The problem statement goes like this: Given a square array of integers A, we want the minimum sum of a falling path through A. A falling path starts at any element in the first row, and chooses one element from each row. The next row's choice must be in a column that is different from the previous row's column by at most one. There are a few examples listed below which might help to elaborate on the problem:
  1. static void Main(string[] args)  
  2. {  
  3.     var result = minFallingPathSum(new int[,]  
  4.     {  
  5.         { 1, 2, 3 },  
  6.         { 4, 5, 6 },  
  7.         { 7, 8, 9 }  
  8.     });  
  9. }  
The possible paths for A [[1,2,3],[4,5,6],[7,8,9]] are [1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9] [2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9] [3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9] where the falling path with the smallest sum is [1,4,7], so the answer is 12.
 

Solution

 
The most naive approach to this problem is by looping over every element and then find the possible paths and store the sum in an array. And finally find the least value from the stored array as the least path sum or the falling path needed. Given below is the C# code for the approach,
  1. static int minFallingPathSum(int[,] A)  
  2. {  
  3.     int size = A.GetLength(0);  
  4.     int[,] dp = new int[size, size];  
  5.     for (int i = 0; i < size; i++)  
  6.     {  
  7.         for (int j = 0; j < size; j++)  
  8.         {  
  9.             if (i == 0)  
  10.                 dp[i, j] = A[i, j];  
  11.             else  
  12.             {  
  13.                 int lastRow = dp[i - 1, j];  
  14.                 if (j - 1 >= 0)  
  15.                     lastRow = Math.Min(dp[i - 1, j - 1], lastRow);  
  16.   
  17.                 if (j + 1 < size)  
  18.                     lastRow = Math.Min(dp[i - 1, j + 1], lastRow);  
  19.                 dp[i, j] = lastRow + A[i, j];  
  20.             }  
  21.         }  
  22.     }  
  23.     int minSum = int.MaxValue;  
  24.     for (int i = 0; i < size; i++)  
  25.         minSum = Math.Min(minSum, dp[size - 1, i]);  
  26.     return minSum;  
  27. }