Open In App

Maximizing sum of non-consecutive elements in Matrix

Improve
Improve
Like Article
Like
Save
Share
Report

Given a matrix of N*3 where N is the number of rows, the task is to choose an integer value from each row in such a manner that the sum of all the values should be maximum and can’t choose the same column values from two consecutive rows.

Examples:

Input: n = 3
point[ ][ ]= 1 2 5
                  3 1 1
                  3 3 3 
Output: 11
Explanation: Choose 5 from first row, 3 from the second row and 3 from third row, maximum sum is 11.

Input: n = 3
point[ ][ ]= 10 40 70
                  20 50 80
                  30 60 90
Output: 210

Approach: To solve the problem follow the below idea:

The idea is to apply Dynamic Programming(Memoization) to solve this problem Recursively. We will recursively call all the subproblems and the result of these subproblems will store in an dp array of similar size(N*3) to decrease the redundant repeating calculations. The Base Case for this problem will be the last row so We will assign the last row values of dp array with the last row values of given N*3 array.

Below are the steps for the above approach:

  • Initialize a 2d array dp of size N*3(N rows and 3 columns) with -1 to implement the Memoization.
  • Initialize the last row of created dp by the last row of the given matrix because it will be our base case.
  • Call three recursive calls from the first row corresponding to columns 1st, 2nd, and 3rd.
  • In the recursive call, check that the value of dp array corresponding to the respective row and col is -1 or not. If the value is not equal to -1 then, simply return this value otherwise calculate the value and update the dp array for the same row and col so further we can directly use this value and no need for computations.
  • Return the max of all three recursive calls.

Below is the code for the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
int maximumPointsUtil(int index, int dp[],
                      vector<vector<int> >& points)
{
    if (dp[index] != -1)
        return dp[index];
    int row = index / 3;
    int col = index % 3;
    if (col == 0) {
        dp[index]
            = points[row][col]
              + max(
                    maximumPointsUtil(index + 4, dp, points),
                    maximumPointsUtil(index + 5, dp, points));
        return dp[index];
    }
    else if (col == 1) {
        dp[index]
            = points[row][col]
              + max(
                    maximumPointsUtil(index + 2, dp, points),
                    maximumPointsUtil(index + 4, dp, points));
        return dp[index];
    }
    else
    {
        dp[index]
            = points[row][col]
              + max(
                    maximumPointsUtil(index + 1, dp, points),
                    maximumPointsUtil(index + 2, dp, points));
        return dp[index];
    }
}
int maximumPoints(vector<vector<int> >& points, int n)
{
    int dp[n * 3];
    memset(dp, -1, sizeof(dp));
    dp[n * 3 - 1] = points[n - 1][2];
    dp[n * 3 - 2] = points[n - 1][1];
    dp[n * 3 - 3] = points[n - 1][0];
    int first = maximumPointsUtil(0, dp, points);
    int second = maximumPointsUtil(1, dp, points);
    int third = maximumPointsUtil(2, dp, points);
    return max(first, max(second, third));
}
 
// Drivers code
int main()
{
    vector<vector<int> > points
        = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
    int n = points.size();
 
    // Function Call
    cout << maximumPoints(points, n);
    return 0;
}


Java




import java.util.Arrays;
import java.util.Vector;
 
class Main {
    public static int maximumPointsUtil(int index, int[] dp, Vector<Vector<Integer> > points)
    {
        if (dp[index] != -1)
            return dp[index];
 
        int row = index / 3;
        int col = index % 3;
 
        if (col == 0) {
            dp[index] = points.get(row).get(col)
                        + Math.max(maximumPointsUtil(index + 4, dp, points), maximumPointsUtil(index + 5, dp, points));
            return dp[index];
        }
        else if (col == 1) {
            dp[index] = points.get(row).get(col)
                        + Math.max(maximumPointsUtil(index + 2, dp, points), maximumPointsUtil(index + 4, dp, points));
            return dp[index];
        }
        else {
            dp[index] = points.get(row).get(col)
                        + Math.max(maximumPointsUtil(index + 1, dp, points), maximumPointsUtil(index + 2, dp, points));
            return dp[index];
        }
    }
 
    public static int maximumPoints(Vector<Vector<Integer> > points, int n)
    {
        int[] dp = new int[n * 3];
        Arrays.fill(dp, -1);
        dp[n * 3 - 1] = points.get(n - 1).get(2);
        dp[n * 3 - 2] = points.get(n - 1).get(1);
        dp[n * 3 - 3] = points.get(n - 1).get(0);
        int first = maximumPointsUtil(0, dp, points);
        int second = maximumPointsUtil(1, dp, points);
        int third = maximumPointsUtil(2, dp, points);
        return Math.max(first, Math.max(second, third));
    }
 
    public static void main(String[] args)
    {
        Vector<Vector<Integer> > points = new Vector<>();
        points.add(new Vector<>(Arrays.asList(1, 2, 5)));
        points.add(new Vector<>(Arrays.asList(3, 1, 1)));
        points.add(new Vector<>(Arrays.asList(3, 3, 3)));
 
        int n = points.size();
        System.out.println(maximumPoints(points, n));
    }
}
// THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)


Python3




def maximumPointsUtil(index, dp, points):
    if dp[index] != -1:
        return dp[index]
    row = index // 3
    col = index % 3
    if col == 0:
        dp[index] = points[row][col] + max(maximumPointsUtil(index + 4, dp, points), maximumPointsUtil(index + 5, dp, points))
        return dp[index]
    elif col == 1:
        dp[index] = points[row][col] + max(maximumPointsUtil(index + 2, dp, points), maximumPointsUtil(index + 4, dp, points))
        return dp[index]
    else:
        dp[index] = points[row][col] + max(maximumPointsUtil(index + 1, dp, points), maximumPointsUtil(index + 2, dp, points))
        return dp[index]
 
def maximumPoints(points):
    n = len(points)
    dp = [-1] * (n * 3)
    dp[n * 3-1] = points[n-1][2]
    dp[n * 3-2] = points[n-1][1]
    dp[n * 3-3] = points[n-1][0]
    first = maximumPointsUtil(0, dp, points)
    second = maximumPointsUtil(1, dp, points)
    third = maximumPointsUtil(2, dp, points)
    return max(first, max(second, third))
 
points = [[1, 2, 5],
          [3, 1, 1],
          [3, 3, 3]]
print(maximumPoints(points))
# THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)


C#




using System;
using System.Collections.Generic;
 
public class Program {
    static int MaximumPointsUtil(int index, int[] dp, List<List<int> > points)
    {
        if (dp[index] != -1)
            return dp[index];
        int row = index / 3;
        int col = index % 3;
        if (col == 0) {
            dp[index] = points[row][col] + Math.Max(MaximumPointsUtil(index + 4, dp, points), MaximumPointsUtil(index + 5, dp, points));
            return dp[index];
        }
        else if (col == 1) {
            dp[index] = points[row][col] + Math.Max(MaximumPointsUtil(index + 2, dp, points), MaximumPointsUtil(index + 4, dp, points));
            return dp[index];
        }
        else {
            dp[index] = points[row][col] + Math.Max(MaximumPointsUtil(index + 1, dp, points), MaximumPointsUtil(index + 2, dp, points));
            return dp[index];
        }
    }
 
    static int MaximumPoints(List<List<int> > points, int n)
    {
        int[] dp = new int[n * 3];
        Array.Fill(dp, -1);
        dp[n * 3 - 1] = points[n - 1][2];
        dp[n * 3 - 2] = points[n - 1][1];
        dp[n * 3 - 3] = points[n - 1][0];
        int first = MaximumPointsUtil(0, dp, points);
        int second = MaximumPointsUtil(1, dp, points);
        int third = MaximumPointsUtil(2, dp, points);
        return Math.Max(first, Math.Max(second, third));
    }
 
    public static void Main()
    {
        List<List<int> > points = new List<List<int> >{
            new List<int>{ 1, 2, 5 },
            new List<int>{ 3, 1, 1 },
            new List<int>{ 3, 3, 3 }
        };
        int n = points.Count;
        Console.WriteLine(MaximumPoints(points, n));
    }
}
// THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)


Javascript




function maximumPointsUtil(index, dp, points) {
  if(dp[index] !== -1) return dp[index];
  const row = Math.floor(index / 3);
  const col = index % 3;
  if(col === 0) {
    dp[index] = points[row][col] + Math.max(maximumPointsUtil(index+4, dp, points), maximumPointsUtil(index+5, dp, points));
    return dp[index];
  }
  else if(col === 1) {
    dp[index] = points[row][col] + Math.max(maximumPointsUtil(index+2, dp, points), maximumPointsUtil(index+4, dp, points));
    return dp[index];
  }
  else {
    dp[index] = points[row][col] + Math.max(maximumPointsUtil(index+1, dp, points), maximumPointsUtil(index+2, dp, points));
    return dp[index];
  }
}
 
function maximumPoints(points, n) {
  const dp = new Array(n*3).fill(-1);
  dp[n*3-1] = points[n-1][2];
  dp[n*3-2] = points[n-1][1];
  dp[n*3-3] = points[n-1][0];
  const first = maximumPointsUtil(0, dp, points);
  const second = maximumPointsUtil(1, dp, points);
  const third = maximumPointsUtil(2, dp, points);
  return Math.max(first, Math.max(second, third));
}
 
const points = [[1, 2, 5], [3, 1, 1], [3, 3, 3]];
const n = points.length;
console.log(maximumPoints(points, n));
// THIS CODE IS CONTRIBUTED BY YASH AGARWAL(YASHAGARWAL2852002)


Output

11










Time Complexity: O(3n), where n is the number of rows/days.
Auxiliary Space: O(3n)

Efficient approach : Using DP Tabulation method ( Iterative approach )

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.

Steps to solve this problem :

  • Create a DP of size n*3 to store the solution of the subproblems .
  • Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP
  • Return the maximum value among dp[0][0], .dp[0][1], dp[0][2] .

Implementation :

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
int maximumPoints(vector<vector<int>>& points) {
    int n = points.size();
    vector<vector<int>> dp(n, vector<int>(3, 0));
 
    // Initialize the DP table with the last row values
    dp[n - 1][0] = points[n - 1][0];
    dp[n - 1][1] = points[n - 1][1];
    dp[n - 1][2] = points[n - 1][2];
 
    // Fill the DP table from the second last row to the first row
    for (int row = n - 2; row >= 0; row--) {
        for (int col = 0; col < 3; col++) {
            // Calculate the maximum points for the current cell based on the adjacent cells
            if (col == 0) {
                dp[row][col] = points[row][col] + max(dp[row + 1][col + 1], dp[row + 1][col + 2]);
            } else if (col == 1) {
                dp[row][col] = points[row][col] + max(dp[row + 1][col - 1], dp[row + 1][col + 1]);
            } else {
                dp[row][col] = points[row][col] + max(dp[row + 1][col - 1], dp[row + 1][col - 2]);
            }
        }
    }
 
    // Find the maximum points in the first row
    return max(dp[0][0], max(dp[0][1], dp[0][2]));
}
 
// Driver Code
int main() {
    vector<vector<int>> points = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
    int result = maximumPoints(points);
 
    cout << result << endl;
    return 0;
}


Java




import java.util.Arrays;
 
public class MaximumPoints {
 
    public static int maximumPoints(int[][] points) {
        int n = points.length;
        int[][] dp = new int[n][3];
 
        // Initialize the DP table with the last row values
        dp[n - 1][0] = points[n - 1][0];
        dp[n - 1][1] = points[n - 1][1];
        dp[n - 1][2] = points[n - 1][2];
 
        // Fill the DP table from the second last row to the first row
        for (int row = n - 2; row >= 0; row--) {
            for (int col = 0; col < 3; col++) {
                // Calculate the maximum points for the current cell based on the adjacent cells
                if (col == 0) {
                    dp[row][col] = points[row][col] + Math.max(dp[row + 1][col + 1], dp[row + 1][col + 2]);
                } else if (col == 1) {
                    dp[row][col] = points[row][col] + Math.max(dp[row + 1][col - 1], dp[row + 1][col + 1]);
                } else {
                    dp[row][col] = points[row][col] + Math.max(dp[row + 1][col - 1], dp[row + 1][col - 2]);
                }
            }
        }
 
        // Find the maximum points in the first row
        return Math.max(dp[0][0], Math.max(dp[0][1], dp[0][2]));
    }
 
    // Driver Code
    public static void main(String[] args) {
        int[][] points = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
        int result = maximumPoints(points);
 
        System.out.println(result);
    }
}


Python3




def maximumPoints(points):
    n = len(points)
     
    # Initialize the DP table with the last row values
    dp = [[0] * 3 for _ in range(n)]
    dp[n - 1][0] = points[n - 1][0]
    dp[n - 1][1] = points[n - 1][1]
    dp[n - 1][2] = points[n - 1][2]
 
    # Fill the DP table from the second last row to the first row
    for row in range(n - 2, -1, -1):
        for col in range(3):
            # Calculate the maximum points for the current cell based on the adjacent cells
            if col == 0:
                dp[row][col] = points[row][col] + max(dp[row + 1][col + 1], dp[row + 1][col + 2])
            elif col == 1:
                dp[row][col] = points[row][col] + max(dp[row + 1][col - 1], dp[row + 1][col + 1])
            else:
                dp[row][col] = points[row][col] + max(dp[row + 1][col - 1], dp[row + 1][col - 2])
 
    # Find the maximum points in the first row
    return max(dp[0][0], max(dp[0][1], dp[0][2]))
 
# Driver Code
if __name__ == "__main__":
    points = [[1, 2, 5], [3, 1, 1], [3, 3, 3]]
    result = maximumPoints(points)
 
    print(result)


C#




using System;
using System.Collections.Generic;
 
class GFG
{
    static int MaximumPoints(List<List<int>> points)
    {
        int n = points.Count;
        int[][] dp = new int[n][];
        for (int i = 0; i < n; i++)
        {
            dp[i] = new int[3];
        }
 
        // Initialize the DP table with the last row values
        dp[n - 1][0] = points[n - 1][0];
        dp[n - 1][1] = points[n - 1][1];
        dp[n - 1][2] = points[n - 1][2];
 
        // Fill the DP table from the second last row to the first row
        for (int row = n - 2; row >= 0; row--)
        {
            for (int col = 0; col < 3; col++)
            {
                // Calculate the maximum points for the current cell based on the adjacent cells
                if (col == 0)
                {
                    dp[row][col] = points[row][col] + Math.Max(dp[row + 1][col + 1],
                                                               dp[row + 1][col + 2]);
                }
                else if (col == 1)
                {
                    dp[row][col] = points[row][col] + Math.Max(dp[row + 1][col - 1],
                                                               dp[row + 1][col + 1]);
                }
                else
                {
                    dp[row][col] = points[row][col] + Math.Max(dp[row + 1][col - 1],
                                                               dp[row + 1][col - 2]);
                }
            }
        }
 
        // Find the maximum points in the first row
        return Math.Max(dp[0][0], Math.Max(dp[0][1], dp[0][2]));
    }
 
    static void Main(string[] args)
    {
        List<List<int>> points = new List<List<int>>
        {
            new List<int> { 1, 2, 5 },
            new List<int> { 3, 1, 1 },
            new List<int> { 3, 3, 3 }
        };
 
        int result = MaximumPoints(points);
 
        Console.WriteLine(result);
    }
}


Javascript




function maximumPoints(points) {
    let n = points.length;
    let dp = new Array(n).fill(0).map(() => new Array(3).fill(0));
 
    // Initialize the DP table with the last row values
    dp[n - 1][0] = points[n - 1][0];
    dp[n - 1][1] = points[n - 1][1];
    dp[n - 1][2] = points[n - 1][2];
 
    // Fill the DP table from the second last row to the first row
    for (let row = n - 2; row >= 0; row--) {
        for (let col = 0; col < 3; col++) {
            // Calculate the maximum points for the current cell based on the adjacent cells
            if (col === 0) {
                dp[row][col] = points[row][col] + Math.max(dp[row + 1][col + 1], dp[row + 1][col + 2]);
            } else if (col === 1) {
                dp[row][col] = points[row][col] + Math.max(dp[row + 1][col - 1], dp[row + 1][col + 1]);
            } else {
                dp[row][col] = points[row][col] + Math.max(dp[row + 1][col - 1], dp[row + 1][col - 2]);
            }
        }
    }
 
    // Find the maximum points in the first row
    return Math.max(dp[0][0], Math.max(dp[0][1], dp[0][2]));
}
 
// Driver Code
let points = [[1, 2, 5], [3, 1, 1], [3, 3, 3]];
let result = maximumPoints(points);
 
console.log(result);


Output:

11

Time Complexity: O(3n), where n is the number of rows/days.

Auxiliary Space: O(3n)



Last Updated : 09 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads