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

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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

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

chevron_right


Output:

35

Time Complexity: O(N*M)

competitive-programming-img




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.