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, , and the answer is minimum value of first row i:e .

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 , 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 likeA = [[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 of7, or(2, 1)and get a weight of8. Since7is lower, we say that the minimum total weight at(1, 0)isdp(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 , and the final answer ismin(A[0][C]) = 12for all C in range 0 to n.

Below is the implementation of above approach.

## C++

`// 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*

*filter_none*

## Java

`// 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*

*filter_none*

## Python 3

`# 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*

*filter_none*

## C#

`// 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*

*filter_none*

**Output:**

12

**Time Complexity:** O(N^{2})

## Recommended Posts:

- Minimum distance to the end of a grid from source
- Minimum cost to cover the given positions in a N*M grid
- Minimum product in a grid of adjacent elements
- Minimum Sum Path in a Triangle
- Minimum Sum Path In 3-D Array
- Minimum odd cost path in a matrix
- Minimum Cost Path with Left, Right, Bottom and Up moves allowed
- Minimum Numbers of cells that are connected with the smallest path between 3 given cells
- Count Magic squares in a grid
- Search a Word in a 2D Grid of characters
- Largest connected component on a grid
- Maximum sum in a 2 x n grid such that no two elements are adjacent
- Check if a word exists in a grid or not
- Unique paths in a Grid with Obstacles
- Collect maximum points in a grid using two traversals

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.