Minimum sum falling path in a NxN grid

Given an square array A of integers of size NxN. The task is to find the minimum sum of a falling path through A.
A falling path will starts at any element in the first row and ends in last row. It chooses one element from each next row. The next row’s choice must be in a column that is different from the previous row’s column by at most one.

Examples:

Input: N = 2
mat[2][2] = 
{{5, 10},
{25, 15}}
Output: 20
Selected elements are 5, 15.

Input: N = 3
mat[3][3] =
{{1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}}
Output: 12
Selected elements are 1, 4, 7.



Approach: This problem has an optimal substructure, meaning that the solutions to sub-problems can be used to solve larger instances of this problem. This makes dynamic programming came into existence.

Let dp[R][C] be the minimum total weight of a falling path starting at [R, C] in first row and reaching to the bottom row of A.

Then, dp[R][C] = A[R][C] + min(dp[R+1, C-1], dp[R+1, C], dp[R+1, C+1]), and the answer is minimum value of first row i:e \underset{C}{min}\; dp(0, C).

We would make an auxiliary array dp to cache intermediate values dp[R][C]. However, we will use A to cache these values. Our goal is to transform the values of A into the values of dp.



We begins processing each row, starting with the second last row. We set A[R][C] = min(A[R+1, C-1], A[R+1, C], A[R+1, C+1]), handling boundary conditions gracefully.

Explanation of above Approach:
Let’s look at the recursion a little more to get a handle on why it works. For an array like A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]], imagine you are at (1, 0) (A[1][0] = 4). You can either go to (2, 0) and get a weight of 7, or (2, 1) and get a weight of 8. Since 7 is lower, we say that the minimum total weight at (1, 0) is dp(1, 0) = 5 + 7 (7 for the original A[R][C].)

After visiting (1, 0), (1, 1), and (1, 2), A [which is storing the values of our dp], looks like [[1, 2, 3], [11, 12, 14], [7, 8, 9]]. We do this procedure again by visiting (0, 0), (0, 1), (0, 2).
We get A=\begin{bmatrix} 12 & 13 & 15\\  11 &  12& 14\\  7 & 8 & 9 \end{bmatrix}, and the final answer is min(A[0][C]) = 12 for all C in range 0 to n.

Below is the implementation of above approach.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to minimum required sum
#include <bits/stdc++.h>
using namespace std;
  
const int n = 3;
  
// Function to return minimum path falling sum
int minFallingPathSum(int (&A)[n][n])
{
  
    // R = Row and C = Column
    // We begin from second last row and keep
    // adding maximum sum.
    for (int R = n - 2; R >= 0; --R) {
        for (int C = 0; C < n; ++C) {
  
            // best = min(A[R+1][C-1], A[R+1][C], A[R+1][C+1])
            int best = A[R + 1][C];
            if (C > 0)
                best = min(best, A[R + 1][C - 1]);
            if (C + 1 < n)
                best = min(best, A[R + 1][C + 1]);
            A[R][C] = A[R][C] + best;
        }
    }
  
    int ans = INT_MAX;
    for (int i = 0; i < n; ++i)
        ans = min(ans, A[0][i]);
    return ans;
}
  
// Driver program
int main()
{
  
    int A[n][n] = { { 1, 2, 3 },
                    { 4, 5, 6 },
                    { 7, 8, 9 } };
  
    // function to print required answer
    cout << minFallingPathSum(A);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program to minimum required sum
  
import java.io.*;
  
class GFG {
static int n = 3;
  
// Function to return minimum path falling sum
static int minFallingPathSum(int A[][])
{
  
    // R = Row and C = Column
    // We begin from second last row and keep
    // adding maximum sum.
    for (int R = n - 2; R >= 0; --R) {
        for (int C = 0; C < n; ++C) {
  
            // best = min(A[R+1][C-1], A[R+1][C], A[R+1][C+1])
            int best = A[R + 1][C];
            if (C > 0)
                best = Math.min(best, A[R + 1][C - 1]);
            if (C + 1 < n)
                best = Math.min(best, A[R + 1][C + 1]);
            A[R][C] = A[R][C] + best;
        }
    }
  
    int ans = Integer.MAX_VALUE;
    for (int i = 0; i < n; ++i)
        ans = Math.min(ans, A[0][i]);
    return ans;
}
  
// Driver program
public static void main (String[] args) {
            int A[][] = { { 1, 2, 3 },
                    { 4, 5, 6 },
                    { 7, 8, 9 } };
  
    // function to print required answer
    System.out.println( minFallingPathSum(A));
    }
}
// This code is contributed by inder_verma..

chevron_right


Python 3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 Program to minimum 
# required sum 
import sys
  
n = 3
  
# Function to return minimum 
# path falling sum 
def minFallingPathSum(A) :
  
    # R = Row and C = Column 
    # We begin from second last row and keep 
    # adding maximum sum. 
    for R in range(n - 2, -1, -1) :
        for C in range(n) :
  
            # best = min(A[R+1][C-1], A[R+1][C],
            # A[R+1][C+1]) 
            best = A[R + 1][C]
            if C > 0 :
                best = min(best, A[R + 1][C - 1])
            if C + 1 < n :
                best = min(best, A[R + 1][C + 1])
  
            A[R][C] = A[R][C] + best
  
    ans = sys.maxsize
  
    for i in range(n) :
        ans = min(ans, A[0][i])
          
    return ans
              
  
  
# Driver code
if __name__ == "__main__" :
  
    A = [ [ 1, 2, 3],
        [ 4, 5, 6],
        [ 7, 8, 9] ]
  
    # function to print required answer 
    print(minFallingPathSum(A))
  
# This code is contributed by 
# ANKITRAI1

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# Program to minimum required sum
  
using System;
  
class GFG {
static int n = 3;
  
// Function to return minimum path falling sum
static int minFallingPathSum(int[,] A)
{
  
    // R = Row and C = Column
    // We begin from second last row and keep
    // adding maximum sum.
    for (int R = n - 2; R >= 0; --R) {
        for (int C = 0; C < n; ++C) {
  
            // best = min(A[R+1,C-1], A[R+1,C], A[R+1,C+1])
            int best = A[R + 1,C];
            if (C > 0)
                best = Math.Min(best, A[R + 1,C - 1]);
            if (C + 1 < n)
                best = Math.Min(best, A[R + 1,C + 1]);
            A[R,C] = A[R,C] + best;
        }
    }
  
    int ans = int.MaxValue;
    for (int i = 0; i < n; ++i)
        ans = Math.Min(ans, A[0,i]);
    return ans;
}
  
// Driver program
public static void Main () {
            int[,] A = { { 1, 2, 3 },
                    { 4, 5, 6 },
                    { 7, 8, 9 } };
  
    // function to print required answer
    Console.WriteLine( minFallingPathSum(A));
    }
}
// This code is contributed by Subhadeep..

chevron_right


Output:

12

Time Complexity: O(N2)



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.