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)
- Consider reading that topic.
- 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++
#include <bits/stdc++.h>
using namespace std;
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];
for ( int i = 0; i < no_of_topics; i++) {
T[i][0] = 0;
}
for ( int j = 0; j < total_time; j++) {
T[0][j] = 0;
}
for ( int i = 1; i < no_of_topics; i++) {
for ( int j = 1; j < total_time; j++) {
if (j < timearr[i]) {
T[i][j] = T[i - 1][j];
}
else {
T[i][j] = max(marksarr[i]
+ T[i - 1][j - timearr[i]],
T[i - 1][j]);
}
}
}
int i = no_of_topics - 1, j = total_time - 1;
int sum = 0;
while (i > 0 && j > 0) {
if (T[i][j] == T[i - 1][j]) {
i--;
}
else {
sum += timearr[i];
j -= timearr[i];
i--;
}
}
int marks = T[no_of_topics - 1][total_time - 1];
if (marks < p)
return -1;
return sum;
}
int main()
{
int n = 4, h = 10, p = 10;
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;
}
|
Java
import java.io.*;
class GFG
{
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];
for ( int i = 0 ; i < no_of_topics; i++)
{
T[i][ 0 ] = 0 ;
}
for ( int j = 0 ; j < total_time; j++)
{
T[ 0 ][j] = 0 ;
}
for ( int i = 1 ; i < no_of_topics; i++)
{
for ( int j = 1 ; j < total_time; j++)
{
if (j < timearr[i])
{
T[i][j] = T[i - 1 ][j];
}
else
{
T[i][j] = Math.max(marksarr[i]
+ T[i - 1 ][j - timearr[i]],
T[i - 1 ][j]);
}
}
}
int i = no_of_topics - 1 , j = total_time - 1 ;
int sum = 0 ;
while (i > 0 && j > 0 )
{
if (T[i][j] == T[i - 1 ][j])
{
i--;
}
else
{
sum += timearr[i];
j -= timearr[i];
i--;
}
}
int marks = T[no_of_topics - 1 ][total_time - 1 ];
if (marks < p)
return - 1 ;
return sum;
}
public static void main (String[] args)
{
int n = 4 , h = 10 , p = 10 ;
int marksarr[] = { 0 , 6 , 4 , 2 , 8 };
int timearr[] = { 0 , 4 , 6 , 2 , 7 };
System.out.println( MaximumMarks(marksarr, timearr, h, n, p));
}
}
|
Python3
import numpy as np
def MaximumMarks(marksarr, timearr, h, n, p) :
no_of_topics = n + 1 ;
total_time = h + 1 ;
T = np.zeros((no_of_topics, total_time));
for i in range (no_of_topics) :
T[i][ 0 ] = 0 ;
for j in range (total_time) :
T[ 0 ][j] = 0 ;
for i in range ( 1 , no_of_topics) :
for j in range ( 1 , total_time) :
if (j < timearr[i]) :
T[i][j] = T[i - 1 ][j];
else :
T[i][j] = max (marksarr[i] +
T[i - 1 ][j - timearr[i]],
T[i - 1 ][j]);
i = no_of_topics - 1 ; j = total_time - 1 ;
sum = 0 ;
while (i > 0 and j > 0 ) :
if (T[i][j] = = T[i - 1 ][j]) :
i - = 1 ;
else :
sum + = timearr[i];
j - = timearr[i];
i - = 1 ;
marks = T[no_of_topics - 1 ][total_time - 1 ];
if (marks < p) :
return - 1 ;
return sum ;
if __name__ = = "__main__" :
n = 4 ; h = 10 ; p = 10 ;
marksarr = [ 0 , 6 , 4 , 2 , 8 ];
timearr = [ 0 , 4 , 6 , 2 , 7 ];
print (MaximumMarks(marksarr, timearr, h, n, p));
|
C#
using System;
class GFG
{
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;
for (i = 0; i < no_of_topics; i++)
{
T[i, 0] = 0;
}
for (j = 0; j < total_time; j++)
{
T[0, j] = 0;
}
for (i = 1; i < no_of_topics; i++)
{
for (j = 1; j < total_time; j++)
{
if (j < timearr[i])
{
T[i, j] = T[i - 1, j];
}
else
{
T[i, j] = Math.Max(marksarr[i]
+ T[i - 1, j - timearr[i]],
T[i - 1, j]);
}
}
}
i = no_of_topics - 1; j = total_time - 1;
int sum = 0;
while (i > 0 && j > 0)
{
if (T[i, j] == T[i - 1, j])
{
i--;
}
else
{
sum += timearr[i];
j -= timearr[i];
i--;
}
}
int marks = T[no_of_topics - 1, total_time - 1];
if (marks < p)
return -1;
return sum;
}
public static void Main (String[] args)
{
int n = 4, h = 10, p = 10;
int []marksarr = { 0, 6, 4, 2, 8 };
int []timearr = { 0, 4, 6, 2, 7 };
Console.WriteLine( MaximumMarks(marksarr, timearr, h, n, p));
}
}
|
Javascript
<script>
function MaximumMarks(marksarr, timearr, h, n, p)
{
let no_of_topics = n + 1;
let total_time = h + 1;
let T = new Array(no_of_topics);
for (let i = 0; i < no_of_topics; i++)
{
T[i] = new Array(total_time);
for (let j = 0; j < total_time; j++)
{
T[i][j] = 0;
}
}
for (let i = 0; i < no_of_topics; i++)
{
T[i][0] = 0;
}
for (let j = 0; j < total_time; j++)
{
T[0][j] = 0;
}
for (let i = 1; i < no_of_topics; i++)
{
for (let j = 1; j < total_time; j++)
{
if (j < timearr[i])
{
T[i][j] = T[i - 1][j];
}
else
{
T[i][j] = Math.max(marksarr[i]
+ T[i - 1][j - timearr[i]],
T[i - 1][j]);
}
}
}
let i = no_of_topics - 1, j = total_time - 1;
let sum = 0;
while (i > 0 && j > 0)
{
if (T[i][j] == T[i - 1][j])
{
i--;
}
else
{
sum += timearr[i];
j -= timearr[i];
i--;
}
}
let marks = T[no_of_topics - 1][total_time - 1];
if (marks < p)
return -1;
return sum;
}
let n = 4, h = 10, p = 10;
let marksarr = [ 0, 6, 4, 2, 8 ];
let timearr = [ 0, 4, 6, 2, 7 ];
document.write( MaximumMarks(marksarr, timearr, h, n, p));
</script>
|
Time Complexity : O (n*t) ( where n is number of topics and t is total time taken)
Space Complexity : O (n*t)
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D vector dp of size h+1.
- Set a base case by initializing the values of DP .
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- Initialize a variable sum to store the final answer and update it by iterating through the Dp.
- At last return and print the final answer stored in sum.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int MaximumMarks( int marksarr[], int timearr[], int h,
int n, int p)
{
vector< int > T(h + 1, 0);
for ( int i = 1; i <= n; i++) {
for ( int j = h; j >= timearr[i]; j--) {
T[j] = max(T[j],
marksarr[i] + T[j - timearr[i]]);
}
}
int sum = 0;
for ( int j = h; j >= 0; j--) {
if (T[j] >= p) {
sum = j;
break ;
}
}
return (sum > 0 ? sum : -1);
}
int main()
{
int n = 4, h = 10, p = 10;
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;
}
|
Java
import java.util.*;
public class Main {
static int MaximumMarks( int marksarr[], int timearr[], int h,
int n, int p)
{
ArrayList<Integer> T = new ArrayList<>(Collections.nCopies(h + 1 , 0 ));
for ( int i = 1 ; i <= n; i++) {
for ( int j = h; j >= timearr[i]; j--) {
T.set(j, Math.max(T.get(j),
marksarr[i] + T.get(j - timearr[i])));
}
}
int sum = 0 ;
for ( int j = h; j >= 0 ; j--) {
if (T.get(j) >= p) {
sum = j;
break ;
}
}
return (sum > 0 ? sum : - 1 );
}
public static void main(String[] args)
{
int n = 4 , h = 10 , p = 10 ;
int marksarr[] = { 0 , 6 , 4 , 2 , 8 };
int timearr[] = { 0 , 4 , 6 , 2 , 7 };
System.out.println(MaximumMarks(marksarr, timearr, h, n, p));
}
}
|
Python
def MaximumMarks(marksarr, timearr, h, n, p):
T = [ 0 ] * (h + 1 )
for i in range ( 1 , n + 1 ):
for j in range (h, timearr[i] - 1 , - 1 ):
T[j] = max (T[j], marksarr[i] + T[j - timearr[i]])
sum = 0
for j in range (h, - 1 , - 1 ):
if T[j] > = p:
sum = j
break
return sum if sum > 0 else - 1
if __name__ = = "__main__" :
n, h, p = 4 , 10 , 10
marksarr = [ 0 , 6 , 4 , 2 , 8 ]
timearr = [ 0 , 4 , 6 , 2 , 7 ]
print (MaximumMarks(marksarr, timearr, h, n, p))
|
C#
using System;
using System.Collections.Generic;
public class MainClass
{
static int MaximumMarks( int [] marksarr, int [] timearr, int h, int n, int p)
{
List< int > T = new List< int >( new int [h + 1]);
for ( int i = 1; i <= n; i++)
{
for ( int j = h; j >= timearr[i]; j--)
{
T[j] = Math.Max(T[j], marksarr[i] + T[j - timearr[i]]);
}
}
int sum = 0;
for ( int j = h; j >= 0; j--)
{
if (T[j] >= p)
{
sum = j;
break ;
}
}
return (sum > 0 ? sum : -1);
}
public static void Main( string [] args)
{
int n = 4, h = 10, p = 10;
int [] marksarr = { 0, 6, 4, 2, 8 };
int [] timearr = { 0, 4, 6, 2, 7 };
Console.WriteLine(MaximumMarks(marksarr, timearr, h, n, p));
}
}
|
Javascript
function MaximumMarks(marksarr, timearr, h, n, p) {
const T = new Array(h + 1).fill(0);
for (let i = 1; i <= n; i++) {
for (let j = h; j >= timearr[i]; j--) {
T[j] = Math.max(T[j], marksarr[i] + T[j - timearr[i]]);
}
}
let sum = 0;
for (let j = h; j >= 0; j--) {
if (T[j] >= p) {
sum = j;
break ;
}
}
return sum > 0 ? sum : -1;
}
const n = 4;
const h = 10;
const p = 10;
const marksarr = [0, 6, 4, 2, 8];
const timearr = [0, 4, 6, 2, 7];
console.log(MaximumMarks(marksarr, timearr, h, n, p));
|
Output:
10
Time Complexity: O (n*h) ( where n is number of topics and t is time left in hour)
Auxiliary Space : O (h)
Last Updated :
08 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...