# Maximum path sum when at most K elements can be picked from a row

• Difficulty Level : Hard
• Last Updated : 04 Apr, 2022

Given a matrix mat[][] of size N * M and an integer K, the task is to find a path from the top-left cell (0, 0) to the bottom-right cell (N–1, M–1) of the given matrix such that:

• One right and downward movement are allowed. i.e., from (i, j) to (i, j-1) and (i+1, j).
• Sum of the elements in the path is maximum and not more than K cells can be chosen from one row.

Examples:

Input: N = 3, M = 3, K = 2, mat = [[2, 10, 8], [8, 8, 8], [0, 1, 0]]
Output: 28
Explanation: The optimal way of choosing cells will be (0, 0) -> (0, 1) -> (1, 1) -> (1, 2) -> (2, 2).

Input: N = 3, M = 3, K = 1, mat = [[0, 0, 4], [0, 5, 0], [3, 0, 2]]
Output: 7
Explanation: The optimal way of choosing cells will be (0, 0) -> (1, 0) -> (1, 1) -> (1, 2) -> (2, 2).

Naive Approach: The easiest approach is to find all the possible paths from top-left to bottom-right and having not more than K cells from a single row. Calculate the maximum path sum among all of them.

Time Complexity: O(M+N-2CN-1)
Auxiliary Space: O(1)

Efficient Approach: The efficient approach to solve the problem is to use dynamic programming based on the following idea:

For any row consider that 1 to K number of elements are chosen from that row.
For any cell (i, j) consider it to be a part of the path choosing l number of cells from that row.
Create a 3D dp array where dp[i][j][l] store the calculated value when cell (i, j) is part of a path having l cells from that row.

• dp[i][j][l] depends on dp[i][j][l-1] and dp[i][j-1][l]
• dp[i][j][0] depends on dp[i-1][j][l] for all value of l from 1 to K (because when row is changed no element from the new row is taken till now).

Follow the below steps to solve this problem :

• Declare a 3D array (say dp) with size N * M * (K + 1).
• Iterate over the given matrix:
• Iterate over all the possible values of l in reverse order (from K-1 to 0):
• Check if the current state of dp has a positive value.
• Then update the dp array for (l + 1)-th state since we include the current value of the grid.
• Again iterate over all the possible values of l:
• Check if the current state of dp has a positive value.
• Then update the downward cell of the current cell if it exists.
• And also update the rightward cell of the current cell if it exists.
• Declare an integer variable ans and initialize it with 0.
• Iterate over all the possible values of l.
• Update ans as max of itself and the dp[N-1][M-1][l].
• Finally, return the ans.

Below is the implementation of the above approach :

## C++

 `// C++ code to implement the approach`   `#include ` `using` `namespace` `std;`   `// Function to find the maximum path sum` `int` `maximumProfits(``int` `n, ``int` `m, ``int` `k,` `                   ``vector >& grid)` `{`   `    ``// Declare a -d array named “dp”` `    ``// with size ‘N’ * ‘M’ * (‘K’ + 1).` `    ``int` `dp[n][m][k + 1];`   `    ``// Initialize the "dp" array with INT_MIN.` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``for` `(``int` `j = 0; j < m; j++) {` `            ``for` `(``int` `l = 0; l < k + 1; l++) {` `                ``dp[i][j][l] = INT_MIN;` `            ``}` `        ``}` `    ``}`   `    ``// Base case.` `    ``dp[0][0][0] = 0;`   `    ``// Iterate over the grid.` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``for` `(``int` `j = 0; j < m; j++) {`   `            ``// Iterate over the possible` `            ``// values of ‘l’ in reverse order.` `            ``for` `(``int` `l = k - 1; l >= 0; l--) {`   `                ``// If the current state` `                ``// of “dp” has positive value` `                ``if` `(dp[i][j][l] >= 0) {`   `                    ``// Update “dp” array for` `                    ``//(‘l’ + 1)-th state since` `                    ``// we include` `                    ``// the current value` `                    ``// of the grid.` `                    ``dp[i][j][l + 1]` `                        ``= max(dp[i][j][l + 1],` `                              ``dp[i][j][l]` `                                  ``+ grid[i][j]);` `                ``}` `            ``}`   `            ``// Again iterate over` `            ``// all possible values of ‘l’.` `            ``for` `(``int` `l = 0; l < k + 1; l++) {`   `                ``// If the current state` `                ``// of “dp” has positive value` `                ``if` `(dp[i][j][l] >= 0) {`   `                    ``// Update the downward cell` `                    ``// of the current cell` `                    ``// if it exists.` `                    ``if` `(i + 1 < n) {` `                        ``dp[i + 1][j][0] = max(` `                            ``dp[i + 1][j][0],` `                            ``dp[i][j][l]);` `                    ``}`   `                    ``// Update the right cell` `                    ``// of the current cell` `                    ``// if it exists.` `                    ``if` `(j + 1 < m) {` `                        ``dp[i][j + 1][l] = max(` `                            ``dp[i][j + 1][l],` `                            ``dp[i][j][l]);` `                    ``}` `                ``}` `            ``}` `        ``}` `    ``}`   `    ``// Declare an integer variable “ans” and` `    ``// initialize it with 0.` `    ``int` `ans = 0;`   `    ``// Iterate over all possible values of l` `    ``for` `(``int` `l = 0; l < k + 1; l++) {`   `        ``// Update ans as max of itself and` `        ``// the dp value for (n -1, m - 1)th` `        ``// cell  for the current value of l` `        ``ans = max(ans, dp[n - 1][m - 1][l]);` `    ``}`   `    ``// Return the “ans”.` `    ``return` `ans;` `}`   `// Driver code` `int` `main()` `{` `    ``int` `N = 3, M = 3, K = 2;` `    ``vector > mat = { { 2, 10, 8 },` `                                 ``{ 8, 8, 8 },` `                                 ``{ 0, 1, 0 } };` `    ``cout << maximumProfits(N, M, K, mat);` `    ``return` `0;` `}`

## Java

 `// JAVA code to implement the approach` `import` `java.util.*;` `class` `GFG {`   `  ``// Function to find the maximum path sum` `  ``public` `static` `int` `    ``maximumProfits(``int` `n, ``int` `m, ``int` `k,` `                   ``ArrayList > grid)` `  ``{`   `    ``// Declare a -d array named “dp”` `    ``// with size ‘N’ * ‘M’ * (‘K’ + 1).` `    ``int` `dp[][][] = ``new` `int``[n][m][k + ``1``];`   `    ``// Initialize the "dp" array with INT_MIN.` `    ``for` `(``int` `i = ``0``; i < n; i++) {` `      ``for` `(``int` `j = ``0``; j < m; j++) {` `        ``for` `(``int` `l = ``0``; l < k + ``1``; l++) {` `          ``dp[i][j][l] = Integer.MIN_VALUE;` `        ``}` `      ``}` `    ``}`   `    ``// Base case.` `    ``dp[``0``][``0``][``0``] = ``0``;`   `    ``// Iterate over the grid.` `    ``for` `(``int` `i = ``0``; i < n; i++) {` `      ``for` `(``int` `j = ``0``; j < m; j++) {`   `        ``// Iterate over the possible` `        ``// values of ‘l’ in reverse order.` `        ``for` `(``int` `l = k - ``1``; l >= ``0``; l--) {`   `          ``// If the current state` `          ``// of “dp” has positive value` `          ``if` `(dp[i][j][l] >= ``0``) {`   `            ``// Update “dp” array for` `            ``//(‘l’ + 1)-th state since` `            ``// we include` `            ``// the current value` `            ``// of the grid.` `            ``dp[i][j][l + ``1``] = Math.max(` `              ``dp[i][j][l + ``1``],` `              ``dp[i][j][l]` `              ``+ grid.get(i).get(j));` `          ``}` `        ``}`   `        ``// Again iterate over` `        ``// all possible values of ‘l’.` `        ``for` `(``int` `l = ``0``; l < k + ``1``; l++) {`   `          ``// If the current state` `          ``// of “dp” has positive value` `          ``if` `(dp[i][j][l] >= ``0``) {`   `            ``// Update the downward cell` `            ``// of the current cell` `            ``// if it exists.` `            ``if` `(i + ``1` `< n) {` `              ``dp[i + ``1``][j][``0``]` `                ``= Math.max(dp[i + ``1``][j][``0``],` `                           ``dp[i][j][l]);` `            ``}`   `            ``// Update the right cell` `            ``// of the current cell` `            ``// if it exists.` `            ``if` `(j + ``1` `< m) {` `              ``dp[i][j + ``1``][l]` `                ``= Math.max(dp[i][j + ``1``][l],` `                           ``dp[i][j][l]);` `            ``}` `          ``}` `        ``}` `      ``}` `    ``}`   `    ``// Declare an integer variable “ans” and` `    ``// initialize it with 0.` `    ``int` `ans = ``0``;`   `    ``// Iterate over all possible values of l` `    ``for` `(``int` `l = ``0``; l < k + ``1``; l++) {`   `      ``// Update ans as max of itself and` `      ``// the dp value for (n -1, m - 1)th` `      ``// cell  for the current value of l` `      ``ans = Math.max(ans, dp[n - ``1``][m - ``1``][l]);` `    ``}`   `    ``// Return the “ans”.` `    ``return` `ans;` `  ``}`   `  ``// Driver code` `  ``public` `static` `void` `main(String[] args)` `  ``{` `    ``int` `N = ``3``, M = ``3``, K = ``2``;` `    ``ArrayList > mat` `      ``= ``new` `ArrayList >();` `    ``ArrayList temp1 = ``new` `ArrayList(` `      ``Arrays.asList(``2``, ``10``, ``8``));` `    ``ArrayList temp2 = ``new` `ArrayList(` `      ``Arrays.asList(``8``, ``8``, ``8``));` `    ``ArrayList temp3 = ``new` `ArrayList(` `      ``Arrays.asList(``0``, ``1``, ``0``));` `    ``mat.add(temp1);` `    ``mat.add(temp2);` `    ``mat.add(temp3);` `    ``System.out.print(maximumProfits(N, M, K, mat));` `  ``}` `}`   `// This code is contributed by Taranpreet`

## Python3

 `# Python code to implement the approach` `import` `sys`   `INT_MIN ``=` `-``sys.maxsize ``-` `1`   `# Function to find the maximum path sum` `def` `maximumProfits(n, m, k,grid):`   `    ``global` `INT_MIN`   `    ``# Declare a -d array named “dp”` `    ``# with size ‘N’ * ‘M’ * (‘K’ + 1).` `    ``# Initialize the "dp" array with INT_MIN.` `    ``dp ``=` `[[[INT_MIN ``for` `i ``in` `range``(k ``+` `1``)] ``for` `j ``in` `range``(m)] ``for` `l ``in` `range``(n)]`   `    ``# Base case.` `    ``dp[``0``][``0``][``0``] ``=` `0`   `    ``# Iterate over the grid.` `    ``for` `i ``in` `range``(n):` `        ``for` `j ``in` `range``(m):`   `            ``# Iterate over the possible` `            ``# values of ‘l’ in reverse order.` `            ``for` `l ``in` `range``(k ``-` `1``,``-``1``,``-``1``):`   `                ``# If the current state` `                ``# of “dp” has positive value` `                ``if` `(dp[i][j][l] >``=` `0``):`   `                    ``# Update “dp” array for` `                    ``#(‘l’ + 1)-th state since` `                    ``# we include` `                    ``# the current value` `                    ``# of the grid.` `                    ``dp[i][j][l ``+` `1``] ``=` `max``(dp[i][j][l ``+` `1``],dp[i][j][l] ``+` `grid[i][j])`   `            ``# Again iterate over` `            ``# all possible values of ‘l’.` `            ``for` `l ``in` `range``(k ``+` `1``):`   `                ``# If the current state` `                ``# of “dp” has positive value` `                ``if` `(dp[i][j][l] >``=` `0``):`   `                    ``# Update the downward cell` `                    ``# of the current cell` `                    ``# if it exists.` `                    ``if` `(i ``+` `1` `< n):` `                        ``dp[i ``+` `1``][j][``0``] ``=` `max``(dp[i ``+` `1``][j][``0``],dp[i][j][l])`   `                    ``# Update the right cell` `                    ``# of the current cell` `                    ``# if it exists.` `                    ``if` `(j ``+` `1` `< m):` `                        ``dp[i][j ``+` `1``][l] ``=` `max``(dp[i][j ``+` `1``][l],dp[i][j][l])`   `    ``# Declare an integer variable “ans” and` `    ``# initialize it with 0.` `    ``ans ``=` `0`   `    ``# Iterate over all possible values of l` `    ``for` `l ``in` `range``(k ``+` `1``):`   `        ``# Update ans as max of itself and` `        ``# the dp value for (n -1, m - 1)th` `        ``# cell  for the current value of l` `        ``ans ``=` `max``(ans, dp[n ``-` `1``][m ``-` `1``][l])`   `    ``# Return the “ans”.` `    ``return` `ans`   `# Driver code` `N, M, K ``=` `3``, ``3``, ``2` `mat ``=` `[ [ ``2``, ``10``, ``8` `],[ ``8``, ``8``, ``8` `],[ ``0``, ``1``, ``0` `] ]` `print``(maximumProfits(N, M, K, mat))`   `# This code is contributed by shinjanpatra.`

## C#

 `// C# code to implement the approach` `using` `System;` `using` `System.Collections.Generic;` `public` `class` `GFG{`   `  ``// Function to find the maximum path sum` `  ``static` `int` `    ``maximumProfits(``int` `n, ``int` `m, ``int` `k,` `                   ``List > grid)` `  ``{`   `    ``// Declare a -d array named “dp”` `    ``// with size ‘N’ * ‘M’ * (‘K’ + 1).` `    ``int``[, ,] dp = ``new` `int``[n,m,k + 1];`   `    ``// Initialize the "dp" array with INT_MIN.` `    ``for` `(``int` `i = 0; i < n; i++) {` `      ``for` `(``int` `j = 0; j < m; j++) {` `        ``for` `(``int` `l = 0; l < k + 1; l++) {` `          ``dp[i, j, l] = Int32.MinValue;` `        ``}` `      ``}` `    ``}`   `    ``// Base case.` `    ``dp[0,0,0] = 0;`   `    ``// Iterate over the grid.` `    ``for` `(``int` `i = 0; i < n; i++) {` `      ``for` `(``int` `j = 0; j < m; j++) {`   `        ``// Iterate over the possible` `        ``// values of ‘l’ in reverse order.` `        ``for` `(``int` `l = k - 1; l >= 0; l--) {`   `          ``// If the current state` `          ``// of “dp” has positive value` `          ``if` `(dp[i,j,l] >= 0) {`   `            ``// Update “dp” array for` `            ``//(‘l’ + 1)-th state since` `            ``// we include` `            ``// the current value` `            ``// of the grid.` `            ``dp[i, j,l+1] = Math.Max(` `              ``dp[i, j,l+1],` `              ``dp[i, j,l]` `              ``+ grid[i][j]);` `          ``}` `        ``}`   `        ``// Again iterate over` `        ``// all possible values of ‘l’.` `        ``for` `(``int` `l = 0; l < k + 1; l++) {`   `          ``// If the current state` `          ``// of “dp” has positive value` `          ``if` `(dp[i,j,l] >= 0) {`   `            ``// Update the downward cell` `            ``// of the current cell` `            ``// if it exists.` `            ``if` `(i + 1 < n) {` `              ``dp[i + 1,j,0]` `                ``= Math.Max(dp[i + 1,j,0],` `                           ``dp[i,j,l]);` `            ``}`   `            ``// Update the right cell` `            ``// of the current cell` `            ``// if it exists.` `            ``if` `(j + 1 < m) {` `              ``dp[i,j + 1,l]` `                ``= Math.Max(dp[i,j + 1,l],` `                           ``dp[i,j, l]);` `            ``}` `          ``}` `        ``}` `      ``}` `    ``}`   `    ``// Declare an integer variable “ans” and` `    ``// initialize it with 0.` `    ``int` `ans = 0;`   `    ``// Iterate over all possible values of l` `    ``for` `(``int` `l = 0; l < k + 1; l++) {`   `      ``// Update ans as max of itself and` `      ``// the dp value for (n -1, m - 1)th` `      ``// cell  for the current value of l` `      ``ans = Math.Max(ans, dp[n - 1,m - 1,l]);` `    ``}`   `    ``// Return the “ans”.` `    ``return` `ans;` `  ``}`   `  ``// Driver code` `  ``static` `public` `void` `Main (){`   `    ``int` `N = 3, M = 3, K = 2;` `    ``List> mat = ``new` `List>();` `    ``mat.Add(``new` `List<``int``> {2, 10, 8 });` `    ``mat.Add(``new` `List<``int``> { 8, 8, 8 });` `    ``mat.Add(``new` `List<``int``> { 0, 1, 0 });`   `    ``Console.Write(maximumProfits(N, M, K, mat));` `  ``}` `}`   `// This code is contributed by hrithikgarg03188.`

## Javascript

 ``

Output

`28`

Time Complexity: O (N * M * K)
Auxiliary Space: O (N * M * K)

My Personal Notes arrow_drop_up
Related Articles