📜  找到准备通过考试的最大主题

📅  最后修改于: 2021-04-30 03:21:47             🧑  作者: Mango

给定三个整数nhp ,其中n是主题数, h是剩余时间(以小时为单位), p是及格分数。还给定两个数组mark []time [] ,其中mark [i]是第i主题的分数, time [i]是学习第i主题所需的时间。任务是找到通过研究最大主题数可以获得的最大分数。

例子:

方法:给定的问题是0/1背包的修改版本,在该版本中,我们必须考虑带一个包,或者忽略该包。
这个问题的变化是给我们一个特定主题所花的时间和剩余的考试时间。

执行:
以与0/1背包问题相同的方式进行操作,如果可以在给定的剩余检查时间内阅读该主题,我们将考虑阅读该主题,否则将忽略该主题并移至下一个主题。这样,我们将计算出学生可以在给定时间范围内得分的最大权重总和。

  • 基本条件:当时间为0或主题数为0时,计算出的分数也将为0
  • 如果剩余时间少于覆盖第i主题所需的时间,则忽略该主题并继续前进。
  • 现在出现两种情况(我们必须找到这两种情况中的最大值)
    1. 考虑阅读该主题。
    2. 忽略那个话题。
  • 现在要找到可以达到的最高分数,我们必须回溯我们考虑阅读的主题的路径。我们将从矩阵的左下开始循环,如果我们在矩阵中考虑了主题权重,则继续增加主题权重。
  • 现在T [no_of_topics-1] [total_time-1]将包含最终标记。
  • 如果最终标记小于通过标记,则打印-1,否则打印计算出的标记。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
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;
}


Java
// 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


Python3
# 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


C#
// 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 */


输出:
10