Maximizing merit points by sequencing activities
Last Updated :
04 Dec, 2023
There are n activities that a person can perform. Each activity has a corresponding merit point for each of the n days. However, the person cannot perform the same activity on two consecutive days. The goal is to find a sequence of activities that maximizes the total merit points earned over the n days.
Input: n = 3, point= [[1, 2, 5], [3, 1, 1], [3, 3, 3]]
Output: 11
Explanation: Geek will learn a new move and earn 5 points then on the second day he will do running and earn 3 points and on the third day he will do fighting and earn 3 points so, the maximum point is 11.
Input: n = 3, point = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}
Output: 3
Approach: To solve the problem follow the below idea:
The approach used is dynamic programming with memoization. The code uses a recursive function, to calculate the maximum points that can be scored in each turn, and stores the result in a 2D array for memoization.
Steps that were to follow the above approach:
- Create a 2D array 'dp' of size '(N+1) x 4' to store the computed values for the subproblems.
- Initialize all values in 'dp' to -1.
- Call the recursive helper function 'helper(points, N-1, 3, dp)' to compute the maximum points that can be earned.
- In the helper function 'helper(points, n, prev, dp)':
- If 'n' is 0, return the maximum point that can be earned in the first row of the 'points' array, such that the selected point is not in the same column as prev.
- If the value for subproblem '(n, prev)' has already been computed and stored in 'dp', return the stored value.
- If not, try all other possible columns besides "prev", and add the point value in points[n][i] to the maximum point that can be earned in the previous row with column i. This will compute the maximum point that can be earned in row n, such that the selected point is not in the same column as "prev." Return the value after storing the result in "dp[n][prev]".
- The final result returned by the function is the maximum point that can be earned in the last row of the points array, such that the selected point is not in the same column as the selected point in the second-to-last row.
Below is the code to implement the above approach:
C++
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int helper(int points[][3], int n, int prev, int dp[][4]) {
if (n == 0) {
int max = 0;
for (int i = 0; i <= 2; i++) {
if (i != prev) {
max = std::max(max, points[0][i]);
}
}
return max;
}
if (dp[n][prev] != -1) {
return dp[n][prev];
}
int max = 0;
for (int i = 0; i <= 2; i++) {
if (i != prev) {
int point = points[n][i] + helper(points, n - 1, i, dp);
max = std::max(max, point);
}
}
return dp[n][prev] = max;
}
int maximumPoints(int points[][3], int N) {
int dp[N + 1][4];
memset(dp, -1, sizeof(dp));
return helper(points, N - 1, 3, dp);
}
int main() {
int N = 3;
int points[][3] = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
int maxPoints = maximumPoints(points, N);
cout << maxPoints << endl;
return 0;
}
Java
// Java code for the above approach:
import java.util.*;
class GFG {
public static int maximumPoints(int points[][], int N)
{
// code here
int dp[][] = new int[N + 1][4];
for (int i = 0; i <= N; i++) {
for (int j = 0; j < 4; j++) {
dp[i][j] = -1;
}
}
// Arrays.fill(dp, -1);
return helper(points, N - 1, 3, dp);
}
static int helper(int points[][], int n, int prev,
int dp[][])
{
if (n == 0) {
int max = 0;
for (int i = 0; i <= 2; i++) {
if (i != prev) {
max = Math.max(max, points[0][i]);
}
}
return max;
}
if (dp[n][prev] != -1) {
return dp[n][prev];
}
int max = 0;
for (int i = 0; i <= 2; i++) {
if (i != prev) {
int point = points[n][i]
+ helper(points, n - 1, i, dp);
max = Math.max(max, point);
}
}
return dp[n][prev] = max;
}
// Driver's code
public static void main(String[] args)
{
int N = 3;
int[][] points
= { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
int maxPoints = maximumPoints(points, N);
// Function Call
System.out.println(maxPoints);
}
}
Python
# Python code for the above approach:
class GFG:
@staticmethod
def maximumPoints(points, N):
dp = [[-1 for _ in range(4)] for _ in range(N + 1)]
return GFG.helper(points, N - 1, 3, dp)
@staticmethod
def helper(points, n, prev, dp):
if n == 0:
max_val = 0
for i in range(3):
if i != prev:
max_val = max(max_val, points[0][i])
return max_val
if dp[n][prev] != -1:
return dp[n][prev]
max_val = 0
for i in range(3):
if i != prev:
point = points[n][i] + GFG.helper(points, n - 1, i, dp)
max_val = max(max_val, point)
dp[n][prev] = max_val
return max_val
# Driver's code
if __name__ == '__main__':
N = 3
points = [[1, 2, 5], [3, 1, 1], [3, 3, 3]]
maxPoints = GFG.maximumPoints(points, N)
print(maxPoints)
# This code is contributed by Prajwal Kandekar
C#
// c# code for the above approach
using System;
class GFG
{
public static int MaximumPoints(int[,] points, int N)
{
int[,] dp = new int[N + 1, 4];
// Initialize dp array with -1
for (int i = 0; i <= N; i++)
{
for (int j = 0; j < 4; j++)
{
dp[i, j] = -1;
}
}
return Helper(points, N - 1, 3, dp);
}
static int Helper(int[,] points, int n, int prev, int[,] dp)
{
if (n == 0)
{
int maximum = 0;
for (int i = 0; i <= 2; i++)
{
if (i != prev)
{
maximum = Math.Max(maximum, points[0, i]);
}
}
return maximum;
}
if (dp[n, prev] != -1)
{
return dp[n, prev];
}
int maxPoints = 0;
for (int i = 0; i <= 2; i++)
{
if (i != prev)
{
int point = points[n, i] + Helper(points, n - 1, i, dp);
maxPoints = Math.Max(maxPoints, point);
}
}
return dp[n, prev] = maxPoints;
}
// Driver's code
public static void Main(string[] args)
{
int N = 3;
int[,] points = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
int maxPoints = MaximumPoints(points, N);
// Function Call
Console.WriteLine(maxPoints);
}
}
JavaScript
class GFG {
static maximumPoints(points, N) {
// Initialize dp array with -1
let dp = Array(N + 1).fill().map(() => Array(4).fill(-1));
return GFG.helper(points, N - 1, 3, dp);
}
static helper(points, n, prev, dp) {
// Base case
if (n === 0) {
let max_val = 0;
for (let i = 0; i < 3; i++) {
if (i !== prev) {
max_val = Math.max(max_val, points[0][i]);
}
}
return max_val;
}
if (dp[n][prev] !== -1) {
return dp[n][prev];
}
// variable to hold the max value
let max_val = 0;
for (let i = 0; i < 3; i++) {
if (i !== prev) {
// Recurssive call to to helper to compute the maximum points
let point = points[n][i] + GFG.helper(points, n - 1, i, dp);
max_val = Math.max(max_val, point);
}
}
dp[n][prev] = max_val;
return max_val;
}
}
// Driver's code
let N = 3;
let points = [[1, 2, 5], [3, 1, 1], [3, 3, 3]];
let maxPoints = GFG.maximumPoints(points, N);
console.log(maxPoints);
Time Complexity: O(n)
Auxiliary Space: O(n^2)
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 .
- Initialize dp with base case.
- declare a variable maxPoints to store the final answer.
- Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP and update maxPoints accordingly.
- Return the final solution stored in maxPoints.
Implementation :
C++
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int maximumPoints(int points[][3], int N) {
int dp[N][3];
// Initialize the DP array with zeros
memset(dp, 0, sizeof(dp));
// Initialize the first row with the values from the first house
for (int i = 0; i < 3; i++) {
dp[0][i] = points[0][i];
}
// Iterate through the houses
for (int i = 1; i < N; i++) {
for (int j = 0; j < 3; j++) {
// Find the maximum points for the current house and color choice
int maxPoints = 0;
for (int k = 0; k < 3; k++) {
if (k != j) {
maxPoints = max(maxPoints, dp[i - 1][k] + points[i][j]);
}
}
dp[i][j] = maxPoints;
}
}
// Find the maximum points in the last row
int maxPoints = 0;
for (int i = 0; i < 3; i++) {
maxPoints = max(maxPoints, dp[N - 1][i]);
}
return maxPoints;
}
//Driver Code
int main() {
int N = 3;
int points[][3] = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
int maxPoints = maximumPoints(points, N);
cout << maxPoints << endl;
return 0;
}
Java
// Java code
public class GFG {
public static int maximumPoints(int[][] points, int N) {
int[][] dp = new int[N][3];
// Initialize the DP array with zeros
for (int i = 0; i < N; i++) {
for (int j = 0; j < 3; j++) {
dp[i][j] = 0;
}
}
// Initialize the first row with the values from the first house
for (int i = 0; i < 3; i++) {
dp[0][i] = points[0][i];
}
// Iterate through the houses
for (int i = 1; i < N; i++) {
for (int j = 0; j < 3; j++) {
// Find the maximum points for the current house and color choice
int maxPoints = 0;
for (int k = 0; k < 3; k++) {
if (k != j) {
maxPoints = Math.max(maxPoints, dp[i - 1][k] + points[i][j]);
}
}
dp[i][j] = maxPoints;
}
}
// Find the maximum points in the last row
int maxPoints = 0;
for (int i = 0; i < 3; i++) {
maxPoints = Math.max(maxPoints, dp[N - 1][i]);
}
return maxPoints;
}
public static void main(String[] args) {
int N = 3;
int[][] points = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
int maxPoints = maximumPoints(points, N);
System.out.println(maxPoints);
}
}
Python3
def maximum_points(points):
N = len(points)
dp = [[0 for _ in range(3)] for _ in range(N)]
# Initialize the first row with the values from the first house
for i in range(3):
dp[0][i] = points[0][i]
# Iterate through the houses
for i in range(1, N):
for j in range(3):
# Find the maximum points for the current house and color choice
max_points = 0
for k in range(3):
if k != j:
max_points = max(max_points, dp[i - 1][k] + points[i][j])
dp[i][j] = max_points
# Find the maximum points in the last row
max_points = max(dp[N - 1])
return max_points
# Driver code
points = [
[1, 2, 5],
[3, 1, 1],
[3, 3, 3]
]
max_points = maximum_points(points)
print(max_points)
C#
using System;
class Program
{
static int MaximumPoints(int[,] points, int N)
{
int[,] dp = new int[N, 3];
// Initialize the DP array with zeros
for (int i = 0; i < N; i++)
{
for (int j = 0; j < 3; j++)
{
dp[i, j] = 0;
}
}
// Initialize the first row with the values from the first house
for (int i = 0; i < 3; i++)
{
dp[0, i] = points[0, i];
}
// Iterate through the houses
for (int i = 1; i < N; i++)
{
for (int j = 0; j < 3; j++)
{
// Find the maximum points for the current house and color choice
int maxPoints = 0;
for (int k = 0; k < 3; k++)
{
if (k != j)
{
maxPoints = Math.Max(maxPoints, dp[i - 1, k] + points[i, j]);
}
}
dp[i, j] = maxPoints;
}
}
// Find the maximum points in the last row
int maxPointsResult = 0;
for (int i = 0; i < 3; i++)
{
maxPointsResult = Math.Max(maxPointsResult, dp[N - 1, i]);
}
return maxPointsResult;
}
// Driver Code
static void Main()
{
int N = 3;
int[,] points = { { 1, 2, 5 }, { 3, 1, 1 }, { 3, 3, 3 } };
int maxPoints = MaximumPoints(points, N);
Console.WriteLine(maxPoints);
}
}
JavaScript
function maximumPoints(points, N) {
const dp = new Array(N).fill(0).map(() => new Array(3).fill(0));
// Initialize the first row with the values from the first house
for (let i = 0; i < 3; i++) {
dp[0][i] = points[0][i];
}
// Iterate through the houses
for (let i = 1; i < N; i++) {
for (let j = 0; j < 3; j++) {
// Find the maximum points for the current house and color choice
let maxPoints = 0;
for (let k = 0; k < 3; k++) {
if (k !== j) {
maxPoints = Math.max(maxPoints, dp[i - 1][k] + points[i][j]);
}
}
dp[i][j] = maxPoints;
}
}
// Find the maximum points in the last row
let maxPoints = 0;
for (let i = 0; i < 3; i++) {
maxPoints = Math.max(maxPoints, dp[N - 1][i]);
}
return maxPoints;
}
// Driver Code
const N = 3;
const points = [[1, 2, 5], [3, 1, 1], [3, 3, 3]];
const maxPoints = maximumPoints(points, N);
console.log(maxPoints);
Output:
11
Time Complexity: O(3n)
Auxiliary Space: O(3n)
Related Articles:
Similar Reads
Maximizing Merit Points in Training Program Geek is going for a training program. He can perform any of these activities: Running, Fighting, and Learning Practice. Each activity has some point on each day. As Geek wants to improve all his skills, he can't do the same activity on two consecutive days. Help Geek to maximize his merit points as
15+ min read
Maximum points by removing Identical Items Given an array arr[] of size N (1 <= N <= 100), which consists of positive numbers representing different items, two items in the array will be treated as identical if arr[i] == arr[j]. In each round, you can select k consecutive identical items, then remove all identical items, and gain k*k p
8 min read
Activity Selection Problem | Greedy Algo-1 Given n activities with start times in start[] and finish times in finish[], find the maximum number of activities a single person can perform without overlap. A person can only do one activity at a time. Examples: Input: start[] = [1, 3, 0, 5, 8, 5], finish[] = [2, 4, 6, 7, 9, 9]Output: 4Explanatio
13 min read
Activity Selection Problem | Greedy Algo-1 Given n activities with start times in start[] and finish times in finish[], find the maximum number of activities a single person can perform without overlap. A person can only do one activity at a time. Examples: Input: start[] = [1, 3, 0, 5, 8, 5], finish[] = [2, 4, 6, 7, 9, 9]Output: 4Explanatio
13 min read
Job Sequencing Problem - Loss Minimization We are given N jobs numbered 1 to N. For each activity, let Ti denotes the number of days required to complete the job. For each day of delay before starting to work for job i, a loss of Li is incurred. We are required to find a sequence to complete the jobs so that overall loss is minimized. We can
8 min read
Maximum Profit By Choosing A Subset Of Intervals (Using Priority-Queue) Given a list intervals of n intervals, the ith element [s, e, p] denotes the starting point s, ending point e, and the profit p earned by choosing the ith interval. Find the maximum profit one can achieve by choosing a subset of non-overlapping intervals. Two intervals [s1, e1, p1] and [s2, e2, p2]
8 min read