Find maximum topics to prepare in order to pass the exam

Given three integer n, h and p where n is the number of topics, h is the time left (in hours) and p is the passing marks. Also given two arrays marks[] and time[] where marks[i] is the marks for the ith topic and time[i] is the time required to learn the ith topic. The task is to find the maximum marks that can be obtained by studying maximum number of topics.

Examples:

Input: n = 4, h = 10, p = 10, marks[] = {6, 4, 2, 8}, time[] = {4, 6, 2, 7}
Output: 10
Either the topics with marks marks[2] and marks[3]
can be prepared or marks[0] and marks[1] can be prepared
Both cases will lead to 10 marks in total
which are equal to the passing marks.

Input: n = 5, h = 40, p = 21, marks[] = {10, 10, 10, 10, 3}, time[] = {12, 16, 20, 24, 8}
Output: 36

Approach: The given problem is a modified version of 0/1 Knapsack where we have to either consider taking a bag or else ignore that bag.
What changes in this question is the constraint conditions that we are given the time a particular topic takes and maximum time left for the exams.

Implementation:
Proceeding in the same way as 0/1 Knapsack problem we will be consider reading a topic if it can be read in the given leftover time for the exam otherwise ignore that topic and move to next topic. This way we will calculate the maximum weightage marks sum that a student can score in the given time frame.

  • Base conditions: When time is 0 or number of topics is 0 then the calculated marks will also be 0.
  • If the leftover time is less than the time needed to cover the ith topic then ignore that topic and move forward.
  • Now two cases arise (We have to find the maximum of the two)
    1. Consider reading that topic.
    2. Ignore that topic.
  • Now to find the maximum marks that can be achieved we have to backtrack our path of topics considered for reading. We will loop from bottom left of matrix to start and keep adding topic weight if we have considered it in the matrix.
  • Now T[no_of_topics-1][total_time-1] will contain the final marks.
  • If the final marks are less than the passing marks then print -1 else print the calculated marks.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the maximum marks
// by considering topics which can be
// completed in the given time duration
int MaximumMarks(int marksarr[], int timearr[], 
                             int h, int n, int p)
{
    int no_of_topics = n + 1;
    int total_time = h + 1;
  
    int T[no_of_topics][total_time];
  
    // Initialization
  
    // If we are given 0 time
    // then nothing can be done
    // So all values are 0
    for (int i = 0; i < no_of_topics; i++) {
        T[i][0] = 0;
    }
  
    // If we are given 0 topics
    // then the time required
    // will be 0 for sure
    for (int j = 0; j < total_time; j++) {
        T[0][j] = 0;
    }
  
    // Calculating the maximum marks
    // that can be achieved under
    // the given time constraints
    for (int i = 1; i < no_of_topics; i++) {
  
        for (int j = 1; j < total_time; j++) {
  
            // If time taken to read that topic
            // is more than the time left now at
            // position j then do no read that topic
            if (j < timearr[i]) {
  
                T[i][j] = T[i - 1][j];
            }
            else {
  
                /*Two cases arise:
                1) Considering current topic
                2) Ignoring current topic
                We are finding maximum of (current topic weightage 
                + topics which can be done in leftover time 
                - current topic time) 
                and ignoring current topic weightage sum
                */
                T[i][j] = max(marksarr[i]
                                  + T[i - 1][j - timearr[i]],
                              T[i - 1][j]);
            }
        }
    }
  
    // Moving upwards in table from bottom right
    // to calculate the total time taken to
    // read the topics which can be done in
    // given time and have highest weightage sum
    int i = no_of_topics - 1, j = total_time - 1;
  
    int sum = 0;
  
    while (i > 0 && j > 0) {
  
        // It means we have not considered
        // reading this topic for
        // max weightage sum
        if (T[i][j] == T[i - 1][j]) {
  
            i--;
        }
        else {
  
            // Adding the topic time
            sum += timearr[i];
  
            // Evaluating the left over time after
            // considering this current topic
            j -= timearr[i];
  
            // One topic completed
            i--;
        }
    }
  
    // It contains the maximum weightage sum
    // formed by considering the topics
    int marks = T[no_of_topics - 1][total_time - 1];
  
    // Condition when exam cannot be passed
    if (marks < p)
        return -1;
  
    // Return the marks that
    // can be obtained after
    // passing the exam
    return sum;
}
  
// Driver code
int main()
{
    // Number of topics, hours left
    // and the passing marks
    int n = 4, h = 10, p = 10;
  
    // n+1 is taken for simplicity in loops
    // Array will be indexed starting from 1
    int marksarr[n + 1] = { 0, 6, 4, 2, 8 };
    int timearr[n + 1] = { 0, 4, 6, 2, 7 };
  
    cout << MaximumMarks(marksarr, timearr, h, n, p);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.io.*;
  
class GFG
{
      
// Function to return the maximum marks
// by considering topics which can be
// completed in the given time duration
static int MaximumMarks(int marksarr[], int timearr[], 
                            int h, int n, int p)
{
    int no_of_topics = n + 1;
    int total_time = h + 1;
  
    int T[][] = new int[no_of_topics][total_time];
  
    // Initialization
  
    // If we are given 0 time
    // then nothing can be done
    // So all values are 0
    for (int i = 0; i < no_of_topics; i++) 
    {
        T[i][0] = 0;
    }
  
    // If we are given 0 topics
    // then the time required
    // will be 0 for sure
    for (int j = 0; j < total_time; j++) 
    {
        T[0][j] = 0;
    }
  
    // Calculating the maximum marks
    // that can be achieved under
    // the given time constraints
    for (int i = 1; i < no_of_topics; i++) 
    {
  
        for (int j = 1; j < total_time; j++)
        {
  
            // If time taken to read that topic
            // is more than the time left now at
            // position j then do no read that topic
            if (j < timearr[i])
            {
  
                T[i][j] = T[i - 1][j];
            }
            else
            {
  
                /*Two cases arise:
                1) Considering current topic
                2) Ignoring current topic
                We are finding maximum of (current topic weightage 
                + topics which can be done in leftover time 
                - current topic time) 
                and ignoring current topic weightage sum
                */
                T[i][j] = Math.max(marksarr[i]
                                + T[i - 1][j - timearr[i]],
                            T[i - 1][j]);
            }
        }
    }
  
    // Moving upwards in table from bottom right
    // to calculate the total time taken to
    // read the topics which can be done in
    // given time and have highest weightage sum
    int i = no_of_topics - 1, j = total_time - 1;
  
    int sum = 0;
  
    while (i > 0 && j > 0
    {
  
        // It means we have not considered
        // reading this topic for
        // max weightage sum
        if (T[i][j] == T[i - 1][j])
        {
  
            i--;
        }
        else 
        {
  
            // Adding the topic time
            sum += timearr[i];
  
            // Evaluating the left over time after
            // considering this current topic
            j -= timearr[i];
  
            // One topic completed
            i--;
        }
    }
  
    // It contains the maximum weightage sum
    // formed by considering the topics
    int marks = T[no_of_topics - 1][total_time - 1];
  
    // Condition when exam cannot be passed
    if (marks < p)
        return -1;
  
    // Return the marks that
    // can be obtained after
    // passing the exam
    return sum;
}
  
    // Driver code
    public static void main (String[] args) 
    {
        // Number of topics, hours left
        // and the passing marks
        int n = 4, h = 10, p = 10;
      
        // n+1 is taken for simplicity in loops
        // Array will be indexed starting from 1
        int marksarr[] = { 0, 6, 4, 2, 8 };
        int timearr[] = { 0, 4, 6, 2, 7 };
      
        System.out.println( MaximumMarks(marksarr, timearr, h, n, p));
    }
}
  
// This code is contributed by vt_m

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
import numpy as np
  
# Function to return the maximum marks 
# by considering topics which can be 
# completed in the given time duration 
def MaximumMarks(marksarr, timearr, h, n, p) : 
  
    no_of_topics = n + 1
    total_time = h + 1
  
    T = np.zeros((no_of_topics, total_time)); 
  
    # Initialization 
  
    # If we are given 0 time 
    # then nothing can be done 
    # So all values are 0 
    for i in range(no_of_topics) : 
        T[i][0] = 0
      
    # If we are given 0 topics 
    # then the time required 
    # will be 0 for sure 
    for j in range(total_time) : 
        T[0][j] = 0
      
    # Calculating the maximum marks 
    # that can be achieved under 
    # the given time constraints 
    for i in range(1, no_of_topics) : 
  
        for j in range(1, total_time) : 
  
            # If time taken to read that topic 
            # is more than the time left now at 
            # position j then do no read that topic 
            if (j < timearr[i]) :
  
                T[i][j] = T[i - 1][j]; 
              
            else :
  
                """Two cases arise: 
                1) Considering current topic 
                2) Ignoring current topic 
                We are finding maximum of (current topic weightage 
                + topics which can be done in leftover time 
                - current topic time) 
                and ignoring current topic weightage sum 
                """
                T[i][j] = max(marksarr[i] + 
                              T[i - 1][j - timearr[i]], 
                              T[i - 1][j]); 
  
    # Moving upwards in table from bottom right 
    # to calculate the total time taken to 
    # read the topics which can be done in 
    # given time and have highest weightage sum 
    i = no_of_topics - 1; j = total_time - 1
  
    sum = 0
  
    while (i > 0 and j > 0) : 
  
        # It means we have not considered 
        # reading this topic for 
        # max weightage sum 
        if (T[i][j] == T[i - 1][j]) :
  
            i -= 1
          
        else
  
            # Adding the topic time 
            sum += timearr[i]; 
  
            # Evaluating the left over time after 
            # considering this current topic 
            j -= timearr[i]; 
  
            # One topic completed 
            i -= 1
  
    # It contains the maximum weightage sum 
    # formed by considering the topics 
    marks = T[no_of_topics - 1][total_time - 1]; 
  
    # Condition when exam cannot be passed 
    if (marks < p) :
        return -1
  
    # Return the marks that 
    # can be obtained after 
    # passing the exam 
    return sum
  
# Driver code 
if __name__ == "__main__"
  
    # Number of topics, hours left 
    # and the passing marks 
    n = 4; h = 10; p = 10;
      
    # n+1 is taken for simplicity in loops 
    # Array will be indexed starting from 1
    marksarr = [ 0, 6, 4, 2, 8 ]; 
    timearr = [ 0, 4, 6, 2, 7 ]; 
      
    print(MaximumMarks(marksarr, timearr, h, n, p)); 
  
# This code is contributed by AnkitRai01

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System; 
      
class GFG
{
      
// Function to return the maximum marks
// by considering topics which can be
// completed in the given time duration
static int MaximumMarks(int []marksarr, int []timearr, 
                            int h, int n, int p)
{
    int no_of_topics = n + 1;
    int total_time = h + 1;
  
    int [,]T = new int[no_of_topics,total_time];
    int i,j;
    // Initialization
  
    // If we are given 0 time
    // then nothing can be done
    // So all values are 0
    for (i = 0; i < no_of_topics; i++) 
    {
        T[i, 0] = 0;
    }
  
    // If we are given 0 topics
    // then the time required
    // will be 0 for sure
    for (j = 0; j < total_time; j++) 
    {
        T[0, j] = 0;
    }
  
    // Calculating the maximum marks
    // that can be achieved under
    // the given time constraints
    for (i = 1; i < no_of_topics; i++) 
    {
  
        for (j = 1; j < total_time; j++)
        {
  
            // If time taken to read that topic
            // is more than the time left now at
            // position j then do no read that topic
            if (j < timearr[i])
            {
  
                T[i, j] = T[i - 1, j];
            }
            else
            {
  
                /*Two cases arise:
                1) Considering current topic
                2) Ignoring current topic
                We are finding maximum of (current topic weightage 
                + topics which can be done in leftover time 
                - current topic time) 
                and ignoring current topic weightage sum
                */
                T[i, j] = Math.Max(marksarr[i]
                                + T[i - 1, j - timearr[i]],
                            T[i - 1, j]);
            }
        }
    }
  
    // Moving upwards in table from bottom right
    // to calculate the total time taken to
    // read the topics which can be done in
    // given time and have highest weightage sum
    i = no_of_topics - 1; j = total_time - 1;
  
    int sum = 0;
  
    while (i > 0 && j > 0) 
    {
  
        // It means we have not considered
        // reading this topic for
        // max weightage sum
        if (T[i, j] == T[i - 1, j])
        {
  
            i--;
        }
        else
        {
  
            // Adding the topic time
            sum += timearr[i];
  
            // Evaluating the left over time after
            // considering this current topic
            j -= timearr[i];
  
            // One topic completed
            i--;
        }
    }
  
    // It contains the maximum weightage sum
    // formed by considering the topics
    int marks = T[no_of_topics - 1, total_time - 1];
  
    // Condition when exam cannot be passed
    if (marks < p)
        return -1;
  
    // Return the marks that
    // can be obtained after
    // passing the exam
    return sum;
}
  
    // Driver code
    public static void Main (String[] args) 
    {
        // Number of topics, hours left
        // and the passing marks
        int n = 4, h = 10, p = 10;
      
        // n+1 is taken for simplicity in loops
        // Array will be indexed starting from 1
        int []marksarr = { 0, 6, 4, 2, 8 };
        int []timearr = { 0, 4, 6, 2, 7 };
      
        Console.WriteLine( MaximumMarks(marksarr, timearr, h, n, p));
    }
}
  
/* This code contributed by PrinciRaj1992 */

chevron_right


Output:

10


My Personal Notes arrow_drop_up

Competitive Programmer, Full Stack Developer

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.



Improved By : vt_m, AnkitRai01, princiraj1992