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: 35Input: mat[][] = {Â
{1, 2, 3},Â
{3, 2, 1},Â
{5, 4, 2}Â
Output: 10Â Â
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 <bits/stdc++.h>using namespace std;Â
const int n = 6, m = 6;Â
// Function to find the maximum valuevoid 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 codeint 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 approachclass GFG{Â
static int n = 6, m = 6;Â
// Function to find the maximum valuestatic 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 codepublic 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 npn = 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 approachusing System;Â
class GFG{static int n = 6, m = 6;Â
// Function to find the maximum valuestatic 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 codepublic 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 |
Javascript
<script>// Javascript program for the above approachÂ
const n = 6, m = 6;Â
// Function to find the maximum valuefunction maxSum(arr){    // Dp table     const dp = new Array(n+1).fill(0).map(() => new Array(3).fill(0));Â
    // Fill the dp in bottom    // up manner    for (var i = 0; i < n; i++) {Â
        // Maximum of the three sections        var m1 = 0, m2 = 0, m3 = 0;Â
        for (var j = 0; j < m; j++) {Â
            // Maximum of the first section            if (parseInt(j / (m / 3)) == 0) {                m1 = Math.max(m1, arr[i][j]);            }Â
            // Maximum of the second section            else if (parseInt(j / (m / 3)) == 1) {                m2 = Math.max(m2, arr[i][j]);            }Â
            // Maximum of the third section            else if (parseInt(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    document.write( parseInt(Math.max(Math.max(dp[n][0], dp[n][1]), dp[n][2])) + "<br>");}Â
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 SoumikMondal</script> |
35
Time Complexity: O(n*m), Where n and m are the numbers of rows and number columns in the matrix.
Auxiliary Space: O(n), as we are using extra space for the dp matrix.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
