蓝桥杯 第2945题 课程抢购 C++ Java Python
目录
lenyan算法笔记 · 语雀 《lenyan算法笔记》
个人笔记日常更新。含金量不高。/(ㄒoㄒ)/~~
题目


思路和解题方法
- 首先,定义了一个结构体
Course来表示每门课程的截止时间、等待时间和含金量。- 在
main函数中,首先读入课程数量n,然后读入每门课程的信息,并将它们按照截止时间升序排序。- 接下来,定义了一个二维数组
dp,其中dp[i][j]表示在前i门课程中,截止时间为j时能够获得的最大含金量。- 初始化
dp数组,将所有元素置为 0。- 接着,进行动态规划的状态转移。对于每一门课程
i,遍历所有可能的截止时间j,更新dp[i][j]:
- 如果当前时间
j大于等于课程i的截止时间,并且从当前时间往前推等待时间仍然在有效范围内,则尝试将课程i加入购买考虑,并更新dp[i][j]。- 在更新
dp[i][j]时,可以选择将课程i加入购买考虑或不加入,取两者中含金量更高的那个。- 最终,输出
dp[n][a[n].jie],表示在考虑了所有课程后,在截止时间为最后一门课程的截止时间时能够获得的最大含金量。
c++ 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
struct Course {
    int de, jie, jia; // 截止时间、等待时间、含金量
};
bool cmp(Course a, Course b) {
    return a.jie < b.jie; // 按照截止时间升序排序
}
Course a[55]; // 定义课程数组
int main() {
    int n;
    cin >> n; // 读入课程数量
    // 读入每门课程的信息
    for (int i = 1; i <= n; i++) {
        cin >> a[i].de >> a[i].jie >> a[i].jia;
    }
    sort(a + 1, a + n + 1, cmp); // 按照截止时间排序课程
    long long dp[55][N]; // 定义动态规划数组
    // 动态规划过程
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j < N; j++) {
            dp[i][j] = 0;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < N; j++) {
            dp[i][j] = dp[i - 1][j]; // 初始化当前状态为前一个状态
            if (j >= a[i].jie && j - a[i].de >= 0) {
                dp[i][j] = max(dp[i][j], dp[i - 1][j - a[i].de] + a[i].jia); // 状态转移方程
            }
        }
    }
    cout << dp[n][a[n].jie] << endl; // 输出结果
    return 0;
}
Java 版本(仅供参考)
import java.util.*;
public class Main {
    static class Course {
        int de, jie, jia; // 截止时间、等待时间、含金量
        public Course(int de, int jie, int jia) {
            this.de = de;
            this.jie = jie;
            this.jia = jia;
        }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt(); // 读入课程数量
        Course[] courses = new Course[n + 1]; // 定义课程数组
        // 读入每门课程的信息
        for (int i = 1; i <= n; i++) {
            int de = scanner.nextInt();
            int jie = scanner.nextInt();
            int jia = scanner.nextInt();
            courses[i] = new Course(de, jie, jia);
        }
        Arrays.sort(courses, 1, n + 1, new Comparator<Course>() {
            @Override
            public int compare(Course a, Course b) {
                return a.jie - b.jie; // 按照截止时间升序排序
            }
        });
        long[][] dp = new long[n + 1][N]; // 定义动态规划数组
        // 动态规划过程
        for (int i = 0; i <= n; i++) {
            Arrays.fill(dp[i], 0);
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < N; j++) {
                dp[i][j] = dp[i - 1][j]; // 初始化当前状态为前一个状态
                if (j >= courses[i].jie && j - courses[i].de >= 0) {
                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - courses[i].de] + courses[i].jia); // 状态转移方程
                }
            }
        }
        System.out.println(dp[n][courses[n].jie]); // 输出结果
    }
    static final int N = 100004; // 数组大小
}
Python 版本(仅供参考)
N = 100005
class Course:
    def __init__(self, de, jie, jia):
        self.de = de
        self.jie = jie
        self.jia = jia
if __name__ == "__main__":
    n = int(input()) # 读入课程数量
    courses = [None] * (n + 1) # 定义课程数组
    # 读入每门课程的信息
    for i in range(1, n + 1):
        de, jie, jia = map(int, input().split())
        courses[i] = Course(de, jie, jia)
    courses.sort(key=lambda x: x.jie) # 按照截止时间升序排序
    dp = [[0] * N for _ in range(n + 1)] # 定义动态规划数组
    # 动态规划过程
    for i in range(1, n + 1):
        for j in range(N):
            dp[i][j] = dp[i - 1][j] # 初始化当前状态为前一个状态
            if j >= courses[i].jie and j - courses[i].de >= 0:
                dp[i][j] = max(dp[i][j], dp[i - 1][j - courses[i].de] + courses[i].jia) # 状态转移方程
    print(dp[n][courses[n].jie]) # 输出结果
代码细节:
C++ 代码细节解释:
1. const int N = 1e5+10;
   定义了常量 N,用于表示数组的大小。
2. struct Course { int de, jie, jia; };
   定义了一个结构体 Course,用于表示课程的截止时间、等待时间和含金量。
3. bool cmp(Course a, Course b) { return a.jie < b.jie; }
   自定义了一个比较函数 cmp,用于对课程按照截止时间升序排序。
4. Course a[55];
   定义了课程数组,数组大小为 55。
5. cin >> n;
   从标准输入流读入课程数量。
6. cin >> a[i].de >> a[i].jie >> a[i].jia;
   依次读入每门课程的截止时间、等待时间和含金量。
7. sort(a + 1, a + n + 1, cmp);
   对课程数组按照截止时间进行排序。
8. long long dp[55][N];
   定义了动态规划数组 dp,用于存储动态规划过程中的状态。
9. for (int i = 0; i <= n; i++) { for (int j = 0; j < N; j++) { dp[i][j] = 0; } }
   初始化动态规划数组,将所有元素初始化为 0。
10. dp[i][j] = max(dp[i][j], dp[i - 1][j - a[i].de] + a[i].jia);
   状态转移方程,表示当前状态下的最大含金量。Java 代码细节解释:
1. class Course { int de, jie, jia; }: 
    这定义了一个名为`Course`的普通类,其中包含三个整数成员变量,表示课程的截止时间、等待时间和含金量。
2. static class Course { int de, jie, jia; ... }: 
    这定义了一个名为`Course`的静态嵌套类,与上述普通类类似。
3. Comparator<Course> cmp = new Comparator<Course>() { @Override public int compare(Course a, Course b) { return a.jie - b.jie; } };: 
    这创建了一个名为`cmp`的`Comparator`实例,用于按截止时间升序比较`Course`对象。
4. Course[] courses = new Course[n + 1];: 
    这声明了一个类型为`Course`的数组`courses`,大小为`n + 1`,用于存储每门课程的信息。
5. courses[i] = new Course(de, jie, jia);: 
    这初始化了一个新的`Course`对象,其截止时间、等待时间和含金量分别为给定的`de`、`jie`和`jia`值,并将其赋值给数组`courses`的第`i`个元素。
6. Arrays.sort(courses, 1, n + 1, cmp);: 
    这使用比较器`cmp`对从索引`1`到`n`的`courses`数组进行排序,排序依据是课程的截止时间`jie`,按升序排列。
7. long[][] dp = new long[n + 1][N];: 
    这声明了一个二维数组`dp`,用于存储动态规划过程中的状态,其中`dp[i][j]`表示考虑前`i`门课程且截止时间为`j`时的最大含金量。
8. for (int i = 0; i <= n; i++) { Arrays.fill(dp[i], 0); }: 
    这将数组`dp`中所有元素初始化为`0`,确保所有状态正确初始化。
9. dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - courses[i].de] + courses[i].jia);: 
    这是动态规划的状态转移方程,计算考虑第`i`门课程时的最大含金量,其中`j`为截止时间。它将当前最大含金量`dp[i][j]`与考虑截止时间为`j - courses[i].de`时的前`i - 1`门课程的最大含金量加上第`i`门课程的含金量`courses[i].jia`进行比较,选择较大者。
Python 代码细节解释:
1. N = 100005:
    这行代码定义了一个常量 N,用于表示数组的大小。
2. class Course::
    这行代码定义了一个名为 Course 的类。
3. def __init__(self, de, jie, jia)::
    这行代码定义了类的构造函数,初始化课程的截止时间、等待时间和含金量。
4. courses = [None] * (n + 1):
    这行代码定义了一个列表,用于存储课程对象。
5. courses.sort(key=lambda x: x.jie):
    这行代码对课程列表按照截止时间升序排序。
6. dp = [[0] * N for _ in range(n + 1)]:
    这行代码初始化了动态规划数组,将所有元素初始化为 0。
7. dp[i][j] = max(dp[i][j], dp[i - 1][j - courses[i].de] + courses[i].jia):
    这行代码是状态转移方程,表示当前状态下的最大含金量。它将当前最大含金量 dp[i][j] 与考虑截止时间为 j - courses[i].de 时的前 i - 1 门课程的最大含金量加上第 i 门课程的含金量 courses[i].jia 进行比较,选择较大者。
觉得有用的话可以点点赞,支持一下。
如果愿意的话关注一下。会对你有更多的帮助。
每天都会不定时更新哦 >人< 。
 笔记可能有点浅薄,误喷。
 📚 《lenyan算法笔记》——探索算法的乐趣
 🌟 欢迎来到《lenyan算法笔记》!这是我日常记录和分享算法学习心得的地方,无论你是初学者还是已经有一定经验的程序员,都能在这里找到有趣的内容。
 🧠 记录学习心得:我用通俗易懂的语言记录了自己学习算法的过程和体会,希望能够帮助到更多有相同兴趣的朋友。
 💻 分享实用代码:每篇笔记都附带了一些实用的代码示例,这些示例不仅是我学习的成果,也可以作为你学习的参考。
 📈 持续学习进步:算法学习是一条持续的道路,我会不断地更新笔记内容,记录自己的学习进步,与你一起成长。
 🔍 分享交流:如果你对我的笔记有任何疑问或建议,都欢迎在评论区与我交流,让我们一起探讨算法的乐趣!
 🚀 如果你也对算法感兴趣,不妨点击链接,一起来探索《lenyan算法笔记》吧:《lenyan算法笔记》 🔥
lenyan算法笔记 · 语雀 《lenyan算法笔记》
 
                    
                 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号