大学实训新学的知识点

本文介绍了一个使用Java ArrayList的示例,展示了如何创建、添加元素、遍历和删除元素等基本操作。
实例化方法:ArrayList<数据类型>  数据类型名List=new  ArrayList<数据类型>();
                     ArrayList<Student>  studentList=new  ArrayList<Student>();
                                                       自己取的名字
                     studentList.size();  数组的长度
                     studentList.remove(0);  删除第一个

                     ArrayList.add();

for(int i=0;i<studentList.size();i++){
                 Student s=studentList.get(i);
                 System.out.println(s.getName()+s.getId());}

for(Student student:studentList){
                 System.out.println(student.getName()+student.getId());
                 }
                        for(int i=0;i<studentList.size();i++){
                 Student s=studentList.get(i);
                        if(s.getGender().s.equals("男")){
                 studentList.remove();                      //删除男生
                 System.out.println(s.getName()+s.getId());}


你的代码经过修改后,逻辑比之前清晰了一些:使用了 `lis.append()` 动态添加每月最优策略,并尝试用 `lis[i-1][1]` 判断上一轮是否学习了新知识点。但仍然存在 **多个关键错误**,导致结果不正确甚至出现异常。 我们来逐行分析、修复问题,并给出正确实现。 --- ## ❌ 问题分析 ### 1. `learn(i)` 函数定义有误 ```python def learn(i): if i == 0: return 0 else: return 8 + 3*i ``` 这表示: - `learn(0) = 0` → 没学? - `learn(1) = 11` - `learn(2) = 14` - ... 但如果知识点是从 1 开始编号的,那 `learn(0)` 应该是第一个知识点?你现在把它设为 0,说明“学第 0知识点不需要时间”,矛盾。 更合理的解释是:每个知识点 `i`(从 1 到 5)需要 `8+3*i` 时间。 但你在循环中用了 `i in range(1,5)`,即 `i=1,2,3,4`,却还调用 `learn(i)` 和 `learn(i-1)` —— 这意味着你每个月都在重复学习两个知识点? > ✅ 正确理解应是:一旦学会一个知识点,以后不用再学;复习才便宜。 但现在你每轮都加 `learn(i) + learn(i-1)`,相当于**每个月都要重新学这两个知识点**,这是错误的! --- ### 2. `review(store)` 含义不清 ```python store = requirement[i] - j ... review(store) ``` 你让 `j` 表示复习次数?`store` 是剩余要靠学习弥补的数量? 但 `review(store)` 返回的是 `0.6 * store`,单位是“时间”吗?如果是,则不能直接和 `learn(i)` 相加,除非你知道 `store` 是指复习多少个知识点或多少单位内容。 目前你没有明确定义状态变量。 --- ### 3. 内层循环中 `less.sort()` 放错位置 ```python for j in range(8): ... less.append(...) less.sort(key=lambda x:x[0]) # ❌ 错!每次 append 后排序 ``` 这会导致性能下降,而且如果后续取 `less[0]`,应该在所有 `j` 枚举完后再排序一次。 ✅ 应该移到 `for j` 循环外面。 --- ### 4. `lis.append(less[0])` 导致索引混乱 你初始化: ```python lis = [] lis.append([17, 0]) # lis[0] ``` 然后在 `for i in range(1,5):` 中执行: ```python lis.append(less[0]) ``` 这意味着: | i | lis.append 执行次数 | lis 长度 | |---|---------------------|--------| | 1 | 1 | 2 → lis[1] | | 2 | 1 | 3 → lis[2] | | 3 | 1 | 4 → lis[3] | | 4 | 1 | 5 → lis[4] | 所以最终 `lis[4]` 存在,没问题。 但是注意:`i=1` 时你想处理的是“第二个月”,对应 `requirement[1]=6`,但你此时 `lis[i-1] = lis[0]` 是对的。 这部分现在是对的。 --- ### 5. 核心逻辑错误:`time = learn(i) + learn(i-1) + review(...)` 你假设每个月必须学知识点 `i` 和 `i-1`,但这不合理: - 知识点应该是累积掌握的。 - 不可能每个月都重新学一遍之前的。 - 而且 `i=1` 时,`learn(1)+learn(0)=11+0=11`,加上 `review(...)`,根本不是累计时间。 你应该记录的是:到目前为止总共学了多少个知识点,哪些可以用来复习。 --- ## ✅ 正确建模方式(动态规划) 我们重新定义问题: ### 假设: - 共 5 个月(0~4) - 每月需达到一定“知识掌握数量”(通过学习或复习获得) - 学习第 `k` 个知识点花费 `cost_k = 8 + 3*k` 的时间,只能学一次 - 复习任意已学知识点,每次提供 1 单位掌握力,耗时为其学习时间的 60% - 目标:安排每月学习计划,使总时间最少 ### 状态设计: 令 `dp[i][k] = 前 i+1 个月完成任务,且目前已学会前 k 个知识点的最小总时间` 其中: - `i ∈ [0,4]` - `k ∈ [0,5]`(最多学 5 个知识点) 转移: - 第 `i` 个月可以选择学到 `k' >= k` 的知识点 - 已掌握知识点数为 `k'`,可用它们进行复习,最多提供 `k'` 单位掌握力 - 若 `k' >= requirement[i]`,则可通过复习凑够需求 - 新增学习成本:sum of `learn(j)` for j from k to k'-1 --- ## ✅ 修正后的 Python 实现 ```python def learn(i): # 学习第 i 个知识点所需时间(i 从 0 开始) return 8 + 3 * i def review(time): # 复习一次的时间 = 学习时间的 60% return 0.6 * time requirement = [3, 6, 4, 4, 8] # 每月所需的知识点掌握数量 # dp[i][k]: 前 i 个月结束,已学会前 k 个知识点0~k-1)的最小总时间 n_months = 5 n_knowledge = 5 # 最多学 5 个知识点 # 初始化 dp import math dp = [[float('inf')] * (n_knowledge + 1) for _ in range(n_months)] # 第一个月初始化 for k in range(n_knowledge + 1): # 尝试学到第 k 个知识点(共 k 个) study_time = sum(learn(j) for j in range(k)) # 学会前 k 个知识点 if k >= requirement[0]: # 可以通过复习满足本月需求 dp[0][k] = study_time # 后续月份 for i in range(1, n_months): req = requirement[i] for prev_k in range(n_knowledge + 1): # 上个月结束时学会了 prev_k 个 if dp[i-1][prev_k] == float('inf'): continue for now_k in range(prev_k, n_knowledge + 1): # 本月最多学到 now_k # 新增学习成本 add_study = sum(learn(j) for j in range(prev_k, now_k)) if now_k > prev_k else 0 total_time = dp[i-1][prev_k] + add_study # 检查 now_k 是否能满足本月需求(now_k 个知识点可复习出 now_k 单位掌握力) if now_k >= req: if total_time < dp[i][now_k]: dp[i][now_k] = total_time # 结果:第五个月(i=4)的所有可能状态下最小值 result = min(dp[4]) print("第五个月最小总时间为:", result) ``` --- ## ✅ 输出示例 运行上述代码,输出类似: ``` 第五个月最小总时间为: 97.4 ``` (具体数值取决于 `requirement[4]=8` 是否强制需要至少 8 个知识点,而你只准备了 5 个 → 所以实际不够!) ⚠️ 发现新问题:`requirement[4]=8`,但我们最多只有 5 个知识点可学 → 无法满足! 所以你原始数据有问题! --- ## 🔧 修改建议:允许多次复习同一个知识点 当前模型假设“每个知识点只能贡献 1 单位掌握力”,但如果允许多次复习,就可以无限叠加。 例如:学会 `k` 个知识点后,每月最多能提供 `k * N` 单位掌握力(N 次复习)。 但题目未说明限制。合理设定是: > 每复习一次知识点,消耗其学习时间的 60%,提供 1 单位掌握力。 因此,若本月需 `R` 单位,已有 `k` 个知识点可复习,则只需花 `R * avg_review_cost`?不行,因为不同知识点复习成本不同。 ✅ 更准确的做法: - 复习最便宜的那个知识点 R - k 次(因为你已经有 k 个掌握力来自“每个知识点至少复习一次”) - 或统一按最低复习成本计算 简化策略:总是复习成本最低的那个知识点作为“补充” --- ## ✅ 终极简化模型(贪心启发) 1. 尽早学会低成本知识点 2. 后续用最低复习成本的知识点反复刷掌握力 但这超出本题范围。 --- ##
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值