Open In App

Maximizing merit points by sequencing activities

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:

Below is the code to implement the above approach:




#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 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 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# 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);
    }
}




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);

Output
11













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 :

Implementation :




#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 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);
    }
}




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)




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);
    }
}




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:


Article Tags :