青训营笔记之及格的组合方式探索 | 豆包MarsCode AI刷题

117 阅读3分钟

问题描述

小S在学校选择了3门必修课和n门选修课程来响应全面发展的教育政策。现在期末考核即将到来,小S想知道他所有课程的成绩有多少种组合方式能使他及格。及格的条件是所有课程的平均分不低于60分。每门课程的成绩是由20道选择题决定,每题5分,答对得分,答错不得分。为了计算方便,你需要将结果对202220222022取模。

测试样例

样例1:

输入:n = 3
输出:'19195617'

样例2:

输入:n = 6
输出:'135464411082'

样例3:

输入:n = 49
输出:'174899025576'

样例4:

输入:n = 201
输出:'34269227409'

样例5:

输入:n = 888
输出:'194187156114'

解题思路

可使用动态规划来解决这个问题,定义一个二维数组 dp,其中 dp[i][j] 表示前 i 门课程总分为 j 的组合数。初始状态 dp[0][0] = 1,表示0门课程总分为0的组合数为1。然后,通过三重循环进行状态转移:外层循环遍历每一门课程 i,中间循环遍历所有可能的总分 j,内层循环遍历当前课程的所有可能分数 k(步长为5),更新 dp[i][j]。最后遍历所有满足平均分不低于60分的总分 j,累加 dp[totalCourses][j] 到 result,并对 MOD 取模,即可得到结果。

算法步骤

  1. 初始化

    • 首先,定义了一个常量 MOD,用于对结果取模。
    • 计算总课程数 totalCourses,即 n + 3
    • 计算最大可能的总分 maxScore,即 100 * totalCourses
    • 初始化一个二维数组 dp,大小为 (totalCourses + 1) * (maxScore + 1),初始值为0。
    • dp[0][0] = 1,表示0门课程总分为0的组合数为1。
  2. 状态转移

    • 对于每一门课程 i(从1到 totalCourses),遍历所有可能的总分 j(从0到 maxScore)。
    • 对于每个总分 j,遍历所有可能的当前课程分数 k(从0到100,步长为5),更新 dp[i][j]
    • 具体更新方式为:dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD,表示当前课程得分为 k 时,前 i-1 门课程总分为 j-k 的组合数。
  3. 结果计算

    • 计算所有满足平均分不低于60分的组合数。
    • 遍历所有可能的总分 j(从 60 * totalCourses 到 maxScore,步长为5),累加 dp[totalCourses][j] 到 result
    • 最终结果对 MOD 取模,并返回结果。

代码实现

public class Main {
    public static String solution(int n) {
        long MOD = 202220222022L;
        int totalCourses = n + 3;
        int maxScore = 100 * totalCourses;
        
        // 初始化dp数组
        long[][] dp = new long[totalCourses + 1][maxScore + 1];
        dp[0][0] = 1;
        
        // 状态转移
        for (int i = 1; i <= totalCourses; i++) {
            for (int j = 0; j <= maxScore; j+=5) {
                for (int k = 0; k <= 100; k = k + 5) {
                    if (j >= k) {
                        dp[i][j] = (dp[i][j] + dp[i - 1][j - k]) % MOD;
                    }
                }
            }
        }
        
        // 计算结果
        long result = 0;
        for (int j = 60 * totalCourses; j <= maxScore; j = j + 5) {
            result = (result + dp[totalCourses][j]) % MOD;
        }
        
        return String.valueOf(result);
    }

}