及格如此简单-动态规划

# 问题描述

为了响应国家全面发展的响应,学校提供了“德”、“智”、“体”、“美”、“劳” 等多门课程供同学们选择学习。

每位同学必修 3 门课程,可选修其他 3 门及以上课程。

小 A 同学选了 `n` 门选修课程,马上要期末考核了,请你帮小 A 同学算一算,如果小 A 同学要及格的话,他所学所有课程的成绩共有多少种组合的方式。

**注意**:

1. 同学的所有学习课程的平均分 >= 60 分 即为及格

2. 每门课程满分 100 分,只有 20 道选择题,每题 5 分,答错 0 分,答对 5 分

3. 成绩的总组合数对 202220222022 取模

## 输入

整数 `n` (`3 <= n <= 1000`)小 A 同学选修的课程数

## 输出

一个整数,表示小 A 同学所学课程能及格的成绩组合方式个数(对 202220222022 取模即可)

状态转移方程:

dp[i][j] = dp[i-1][j] + dp[i-1][j-5] + ... +dp[i-1][j-100]

分别代表第 i 门课0分,5分...100分,总 i 门课总分为 j 的情况。 0<= j' <= (i-1)*100 

动态规划,注意非常坑的一点,要+3,有3门必修课!

public class Main {
    static final long MOD = 202220222022l;

    public static String solution(int n) {
        // Please write your code here
        n += 3;//因为有3门必修,贼坑
        long[] old_dp = new long[101];//动态规划优化空间,2个一维dp即可
        old_dp[0]=1l;
        long[] new_dp = null;
        for(int i=1;i<=n;i++)
        {
            int MaxScore = 100*i;
            new_dp = new long[MaxScore+1];
            for(int  j=0;j<=MaxScore;j+=5)
            {
                for(int k=0;k<=100;k+=5)
                {
                    if(j-k<=(i-1)*100 && j-k>=0)
                    {
                        if (old_dp[j - k] > 0)
                            new_dp[j] = (new_dp[j] + old_dp[j - k]) % MOD;
                    }
                    else if(j-k<0)
                        break;
                }
            }
            old_dp = new_dp;
        }

        long ans=0;
        for(int i=60*n;i<=100*n;i+=5)
            ans = (new_dp[i]+ans)%MOD;
        //System.out.println(ans);
        return String.valueOf(ans);
    }

    public static void main(String[] args) {
        // You can add more test cases here
        System.out.println(solution(3).equals("19195617"));
        System.out.println(solution(6).equals("135464411082"));
        System.out.println(solution(49).equals("174899025576"));
        System.out.println(solution(201).equals("34269227409"));
        System.out.println(solution(888).equals("194187156114"));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值