# Maximize sum by choosing elements from different section of a matrix

Given a matrix of N rows and M columns. It is given that M is a multiple of 3. The columns are divided into 3 sections, the first section is from 0 to m/3-1, the second section is from m/3 to 2m/3-1 and the third section is from 2m/3 to m. The task is to choose a single element from each row and, in adjacent rows, we cannot select from the same section. We have to maximize the sum of the elements chosen.

Examples:

Input: mat[][] = {
{1, 3, 5, 2, 4, 6},
{6, 4, 5, 1, 3, 2},
{1, 3, 5, 2, 4, 6},
{6, 4, 5, 1, 3, 2},
{6, 4, 5, 1, 3, 2},
{1, 3, 5, 2, 4, 6}}
Output: 35

Input: mat[][] = {
{1, 2, 3},
{3, 2, 1},
{5, 4, 2}
Output: 10

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: The problem can be solved using dynamic programming solution by storing the subproblems and reusing them. Create a dp[][] array where dp[i][0] represents the sum of elements of rows from 0 to i taking elements from section 1. Similarly, for dp[i][1] and dp[i][2]. So, print the max(dp[n – 1][0], dp[n – 1][1], dp[n – 1][2].

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach ` `#include ` `using` `namespace` `std; ` ` `  `const` `int` `n = 6, m = 6; ` ` `  `// Function to find the maximum value ` `void` `maxSum(``long` `arr[n][m]) ` `{ ` `    ``// Dp table ` `    ``long` `dp[n + 1][3] = { 0 }; ` ` `  `    ``// Fill the dp in bottom ` `    ``// up manner ` `    ``for` `(``int` `i = 0; i < n; i++) { ` ` `  `        ``// Maximum of the three sections ` `        ``long` `m1 = 0, m2 = 0, m3 = 0; ` ` `  `        ``for` `(``int` `j = 0; j < m; j++) { ` ` `  `            ``// Maximum of the first section ` `            ``if` `((j / (m / 3)) == 0) { ` `                ``m1 = max(m1, arr[i][j]); ` `            ``} ` ` `  `            ``// Maximum of the second section ` `            ``else` `if` `((j / (m / 3)) == 1) { ` `                ``m2 = max(m2, arr[i][j]); ` `            ``} ` ` `  `            ``// Maximum of the third section ` `            ``else` `if` `((j / (m / 3)) == 2) { ` `                ``m3 = max(m3, arr[i][j]); ` `            ``} ` `        ``} ` ` `  `        ``// If we choose element from section 1, ` `        ``// we cannot have selection from same section ` `        ``// in adjacent rows ` `        ``dp[i + 1][0] = max(dp[i][1], dp[i][2]) + m1; ` `        ``dp[i + 1][1] = max(dp[i][0], dp[i][2]) + m2; ` `        ``dp[i + 1][2] = max(dp[i][1], dp[i][0]) + m3; ` `    ``} ` ` `  `    ``// Print the maximum sum ` `    ``cout << max(max(dp[n][0], dp[n][1]), dp[n][2]) << ``'\n'``; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` ` `  `    ``long` `arr[n][m] = { { 1, 3, 5, 2, 4, 6 }, ` `                       ``{ 6, 4, 5, 1, 3, 2 }, ` `                       ``{ 1, 3, 5, 2, 4, 6 }, ` `                       ``{ 6, 4, 5, 1, 3, 2 }, ` `                       ``{ 6, 4, 5, 1, 3, 2 }, ` `                       ``{ 1, 3, 5, 2, 4, 6 } }; ` ` `  `    ``maxSum(arr); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program for the above approach ` `class` `GFG ` `{ ` ` `  `static` `int` `n = ``6``, m = ``6``; ` ` `  `// Function to find the maximum value ` `static` `void` `maxSum(``long` `arr[][]) ` `{ ` `    ``// Dp table ` `    ``long` `[][]dp= ``new` `long``[n + ``1``][``3``]; ` ` `  `    ``// Fill the dp in bottom ` `    ``// up manner ` `    ``for` `(``int` `i = ``0``; i < n; i++) ` `    ``{ ` ` `  `        ``// Maximum of the three sections ` `        ``long` `m1 = ``0``, m2 = ``0``, m3 = ``0``; ` ` `  `        ``for` `(``int` `j = ``0``; j < m; j++)  ` `        ``{ ` ` `  `            ``// Maximum of the first section ` `            ``if` `((j / (m / ``3``)) == ``0``)  ` `            ``{ ` `                ``m1 = Math.max(m1, arr[i][j]); ` `            ``} ` ` `  `            ``// Maximum of the second section ` `            ``else` `if` `((j / (m / ``3``)) == ``1``) ` `            ``{ ` `                ``m2 = Math.max(m2, arr[i][j]); ` `            ``} ` ` `  `            ``// Maximum of the third section ` `            ``else` `if` `((j / (m / ``3``)) == ``2``) ` `            ``{ ` `                ``m3 = Math.max(m3, arr[i][j]); ` `            ``} ` `        ``} ` ` `  `        ``// If we choose element from section 1, ` `        ``// we cannot have selection from same section ` `        ``// in adjacent rows ` `        ``dp[i + ``1``][``0``] = Math.max(dp[i][``1``], dp[i][``2``]) + m1; ` `        ``dp[i + ``1``][``1``] = Math.max(dp[i][``0``], dp[i][``2``]) + m2; ` `        ``dp[i + ``1``][``2``] = Math.max(dp[i][``1``], dp[i][``0``]) + m3; ` `    ``} ` ` `  `    ``// Print the maximum sum ` `    ``System.out.print(Math.max(Math.max(dp[n][``0``], dp[n][``1``]), dp[n][``2``]) + ``"\n"``); ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String[] args) ` `{ ` ` `  `    ``long` `arr[][] = { { ``1``, ``3``, ``5``, ``2``, ``4``, ``6` `}, ` `                    ``{ ``6``, ``4``, ``5``, ``1``, ``3``, ``2` `}, ` `                    ``{ ``1``, ``3``, ``5``, ``2``, ``4``, ``6` `}, ` `                    ``{ ``6``, ``4``, ``5``, ``1``, ``3``, ``2` `}, ` `                    ``{ ``6``, ``4``, ``5``, ``1``, ``3``, ``2` `}, ` `                    ``{ ``1``, ``3``, ``5``, ``2``, ``4``, ``6` `} }; ` ` `  `    ``maxSum(arr); ` `} ` `} ` ` `  `// This code is contributed by PrinciRaj1992 `

## Python3

 `# Python3 program for the above approach  ` `import` `numpy as np ` `n ``=` `6``; m ``=` `6``;  ` ` `  `# Function to find the maximum value  ` `def` `maxSum(arr) : ` ` `  `    ``# Dp table  ` `    ``dp ``=` `np.zeros((n ``+` `1``, ``3``));  ` ` `  `    ``# Fill the dp in bottom  ` `    ``# up manner  ` `    ``for` `i ``in` `range``(n) : ` ` `  `        ``# Maximum of the three sections  ` `        ``m1 ``=` `0``; m2 ``=` `0``; m3 ``=` `0``; ` `         `  `        ``for` `j ``in` `range``(m) : ` `             `  `            ``# Maximum of the first section ` `            ``if` `((j ``/``/` `(m ``/``/` `3``)) ``=``=` `0``) : ` `                ``m1 ``=` `max``(m1, arr[i][j]); ` `                 `  `            ``# Maximum of the second section ` `            ``elif` `((j ``/``/` `(m ``/``/` `3``)) ``=``=` `1``) : ` `                ``m2 ``=` `max``(m2, arr[i][j]); ` `                 `  `            ``# Maximum of the third section ` `            ``elif` `((j ``/``/` `(m ``/``/` `3``)) ``=``=` `2``) : ` `                ``m3 ``=` `max``(m3, arr[i][j]); ` `                 `  `        ``# If we choose element from section 1, ` `        ``# we cannot have selection from same section ` `        ``# in adjacent rows ` `        ``dp[i ``+` `1``][``0``] ``=` `max``(dp[i][``1``], dp[i][``2``]) ``+` `m1; ` `        ``dp[i ``+` `1``][``1``] ``=` `max``(dp[i][``0``], dp[i][``2``]) ``+` `m2; ` `        ``dp[i ``+` `1``][``2``] ``=` `max``(dp[i][``1``], dp[i][``0``]) ``+` `m3;  ` ` `  `    ``# Print the maximum sum  ` `    ``print``(``max``(``max``(dp[n][``0``], dp[n][``1``]), dp[n][``2``]));  ` ` `  `# Driver code  ` `if` `__name__ ``=``=` `"__main__"` `:  ` ` `  `    ``arr ``=` `[[ ``1``, ``3``, ``5``, ``2``, ``4``, ``6` `],  ` `           ``[ ``6``, ``4``, ``5``, ``1``, ``3``, ``2` `],  ` `           ``[ ``1``, ``3``, ``5``, ``2``, ``4``, ``6` `],  ` `           ``[ ``6``, ``4``, ``5``, ``1``, ``3``, ``2` `],  ` `           ``[ ``6``, ``4``, ``5``, ``1``, ``3``, ``2` `],  ` `           ``[ ``1``, ``3``, ``5``, ``2``, ``4``, ``6` `]];  ` ` `  `    ``maxSum(arr);  ` `     `  `# This code is contributed by AnkitRai01 `

## C#

 `// C# program for the above approach ` `using` `System; ` ` `  `class` `GFG ` `{ ` `static` `int` `n = 6, m = 6; ` ` `  `// Function to find the maximum value ` `static` `void` `maxSum(``long` `[,]arr) ` `{ ` `    ``// Dp table ` `    ``long` `[,]dp = ``new` `long``[n + 1, 3]; ` ` `  `    ``// Fill the dp in bottom ` `    ``// up manner ` `    ``for` `(``int` `i = 0; i < n; i++) ` `    ``{ ` ` `  `        ``// Maximum of the three sections ` `        ``long` `m1 = 0, m2 = 0, m3 = 0; ` ` `  `        ``for` `(``int` `j = 0; j < m; j++)  ` `        ``{ ` ` `  `            ``// Maximum of the first section ` `            ``if` `((j / (m / 3)) == 0)  ` `            ``{ ` `                ``m1 = Math.Max(m1, arr[i, j]); ` `            ``} ` ` `  `            ``// Maximum of the second section ` `            ``else` `if` `((j / (m / 3)) == 1) ` `            ``{ ` `                ``m2 = Math.Max(m2, arr[i, j]); ` `            ``} ` ` `  `            ``// Maximum of the third section ` `            ``else` `if` `((j / (m / 3)) == 2) ` `            ``{ ` `                ``m3 = Math.Max(m3, arr[i, j]); ` `            ``} ` `        ``} ` ` `  `        ``// If we choose element from section 1, ` `        ``// we cannot have selection from same section ` `        ``// in adjacent rows  ` `        ``dp[i + 1, 0] = Math.Max(dp[i, 1], dp[i, 2]) + m1; ` `        ``dp[i + 1, 1] = Math.Max(dp[i, 0], dp[i, 2]) + m2; ` `        ``dp[i + 1, 2] = Math.Max(dp[i, 1], dp[i, 0]) + m3; ` `    ``} ` ` `  `    ``// Print the maximum sum ` `    ``Console.Write(Math.Max(Math.Max(dp[n, 0], ` `                                    ``dp[n, 1]), ` `                                    ``dp[n, 2]) + ``"\n"``); ` `} ` ` `  `// Driver code ` `public` `static` `void` `Main(String[] args) ` `{ ` `    ``long` `[,]arr = { { 1, 3, 5, 2, 4, 6 }, ` `                    ``{ 6, 4, 5, 1, 3, 2 }, ` `                    ``{ 1, 3, 5, 2, 4, 6 }, ` `                    ``{ 6, 4, 5, 1, 3, 2 }, ` `                    ``{ 6, 4, 5, 1, 3, 2 }, ` `                    ``{ 1, 3, 5, 2, 4, 6 } }; ` ` `  `    ``maxSum(arr); ` `} ` `} ` ` `  `// This code is contributed by 29AjayKumar `

Output:

```35
```

Time Complexity: O(N*M)

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.