📜  找到最多的主题以通过考试

📅  最后修改于: 2021-09-22 10:39:18             🧑  作者: Mango

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

方法:给定的问题是 0/1 Knapsack 的修改版本,我们要么考虑拿一个袋子,要么忽略那个袋子。
这个问题的变化是限制条件,即我们被赋予特定主题所需的时间和考试剩余的最长时间。
执行:
以与 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 */


Javascript


输出:
10

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程