及格的组合方式探索
问题描述
小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'
编辑区代码
def solution(n):
MOD = 202220222022
dp = [[0] * (20 * (n + 3) + 1) for _ in range(n + 4)]
for k in range(21):
dp[1][k] = 1
for i in range(1, n + 3):
for j in range(20 * (n + 3) + 1):
if dp[i][j] > 0:
for k in range(21):
dp[i + 1][j + k] = (dp[i + 1][j + k] + dp[i][j]) % MOD
else:
break
result = 0
for avg in range(12 * (n + 3), 20 * (n + 3) + 1):
result = (result + dp[3 + n][avg]) % MOD
return str(result)
if __name__ == "__main__":
# 测试样例
print(solution(3) == "19195617")
print(solution(6) == "135464411082")
print(solution(49) == "174899025576")
print(solution(201) == "34269227409")
print(solution(888) == "194187156114")
代码思路
-
问题理解:
- 小S有3门必修课和
n门选修课,每门课的成绩由20道选择题决定,每题5分。 - 需要计算所有课程成绩的组合方式,使得平均分不低于60分(即总分不低于60 * (n + 3)分)。
- 结果需要对202220222022取模。
- 小S有3门必修课和
-
数据结构选择:
- 使用动态规划(DP)来解决组合问题。
- 定义一个二维数组
dp,其中dp[i][j]表示前i门课程总分为j的组合数。
-
算法步骤:
- 初始化:
- 对于第一门课程,所有可能的分数(0到100分)的组合数都为1。
- 状态转移:
- 对于每一门课程
i,遍历所有可能的总分j。 - 如果
dp[i][j]大于0,则对于下一门课程,尝试所有可能的分数增加(0到100分),并更新dp[i+1][j+k]。
- 对于每一门课程
- 结果计算:
- 计算所有课程总分在及格线以上的组合数,并累加结果。
- 最终结果对202220222022取模。
- 初始化:
-
优化:
- 由于每门课程的分数范围是固定的(0到100分),可以通过动态规划有效地计算组合数。
- 使用取模操作避免数值溢出。