LGP1230智力大冲浪 普及/提高- 排序 贪心 标准IO 传统题 时间限制 1000ms 内存限制 125MB 通过/尝试次数 252/327 来源 洛谷 题目描述 小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者 m m 元。先不要太高兴,因为这些钱还不一定都是你的。接下来主持人宣布了比赛规则: 首先,比赛时间分为 n n 个时段,它又给出了很多小游戏,每个小游戏都必须在规定期限 t i t i 前完成。如果一个游戏没能在规定期限前完成,则要从奖励费 m m 元中扣去一部分钱 w i w i , w i w i 为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱!注意:比赛绝对不会让参赛者赔钱! 输入格式 第一行为 m m,表示一开始奖励给每位参赛者的钱; 第二行为 n n,表示有 n n 个小游戏; 第三行有 n n 个数,分别表示游戏 1 1 到 n n 的规定完成期限; 第四行有 n n 个数,分别表示游戏 1 1 到 n n 不能在规定期限前完成的扣款数。 输出格式 输出仅一行,表示小伟能赢取最多的钱。 输入 #1 复制代码 10000 7 4 2 4 3 1 4 6 70 60 50 40 30 20 10 输出 #1 复制代码 9950 提示 对于 100 % 100% 的数据, 1 ≤ n ≤ 500 1≤n≤500, 1 ≤ m ≤ 5 × 1 0 5 1≤m≤5×10 5 , 1 ≤ t i ≤ n 1≤t i ≤n, 1 ≤ w i ≤ 1000 1≤ c++简单代码
时间: 2025-07-12 22:40:37 浏览: 9
<think>嗯,用户想找洛谷LGP1230智力大冲浪的C++实现代码,用贪心算法和排序。首先我得回忆一下这个题目的具体要求。题目大概是说,有多个游戏任务,每个任务有截止时间和罚款,如果不能在截止时间前完成,就会被罚款。目标是如何安排任务顺序,使得总罚款最少。
贪心算法的话,通常这类问题需要排序。那应该按什么排序呢?可能有两种思路:一种是按截止时间从小到大排序,另一种是按罚款金额从大到小排序。因为要尽量减少罚款,所以应该优先处理罚款高的任务,这样即使后面的任务安排不了,罚款高的已经被处理了,总损失更小。
不过,如果两个任务罚款相同,可能截止时间早的应该先处理。所以正确的排序应该是先按罚款金额降序,罚款相同的情况下,截止时间早的优先。然后,需要用一个数组来记录时间点是否被占用,从每个任务的截止时间往前找空闲时间,如果有的话就安排,否则加上罚款。
然后,具体的实现步骤应该是:输入n和m,然后输入每个游戏的时间和罚款。结构体存储每个任务的截止时间和罚款,然后排序。之后初始化一个时间标记数组,记录每个时间点是否被占用。遍历排序后的任务,对于每个任务,从它的截止时间往前找第一个空闲时间,找到就标记占用,否则累加罚款。
需要注意边界条件,比如截止时间可能超过n的情况,这时候直接无法安排,罚款加上。或者时间从1开始还是0开始的问题,题目里可能时间是从1到n的。
然后代码部分,结构体的排序比较函数需要正确实现。然后是时间分配的循环。可能用布尔数组来记录时间点是否被占用。例如,对于一个截止时间为d的任务,从d开始往1找,找到第一个没被占用的位置。如果找不到,就加上罚款。
测试样例的话,比如示例输入,输出是否正确。例如,假设输入是4个任务,时间分别是2 1 2 1,罚款是70 60 50 40。排序后按罚款降序,70、60、50、40。然后依次安排:70的截止时间2,安排到2;60的截止时间1,安排到1;50的截止时间2,但2已经被占用了,所以往前找1,也被占用了,所以罚款;40的截止时间1,同样被占用,罚款。总罚款是50+40=90。所以输出应该是1500-90=1410,对吗?不过要看题目具体怎么描述的。
接下来,用户需要的是C++代码,所以代码结构应该是:输入处理,结构体定义和排序,时间分配,计算总罚款,最后输出结果。可能的注意事项是时间从1开始还是0开始,需要根据题目调整。
然后用户的问题可能涉及贪心算法的正确性证明,或者如何优化时间查找。例如,当截止时间很大时,线性查找可能会慢,但题目数据范围可能允许,因为n可能不大。或者是否有其他方法,比如使用并查集来快速查找空闲时间,这在更高效的方法中常见,比如“并查集优化贪心算法”,但在一般的题解中可能不需要,因为数据量不大。
最后,用户可能需要相关的扩展问题,比如贪心算法的其他应用,或者这道题的变种,比如任务有不同执行时间的情况,这时候问题可能更复杂,可能需要动态规划等。</think>### 洛谷 LGP1230 智力大冲浪 C++ 实现解析
#### 问题分析
题目要求将若干游戏任务按截止时间排序,未完成的任务会扣除对应罚款。目标是**最小化总罚款**,需用贪心算法实现。
**贪心策略**:优先处理罚款高且截止时间早的任务,用时间轴标记已占用的时间段[^1]。
#### 实现步骤
1. **输入处理**:读取任务数和总时间,存储每个任务的截止时间和罚款
2. **排序规则**:按罚款降序排列,罚款相同时按截止时间升序排列
3. **时间分配**:用布尔数组标记时间点占用状态,从截止时间向前寻找空闲位
4. **结果计算**:未分配到时间的任务累加罚款
#### C++ 实现代码
```cpp
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct Task {
int deadline, fine;
} tasks[505];
bool cmp(Task a, Task b) {
if (a.fine != b.fine) return a.fine > b.fine;
return a.deadline < b.deadline;
}
int main() {
int m, n;
cin >> m >> n;
for (int i = 0; i < n; ++i) cin >> tasks[i].deadline;
for (int i = 0; i < n; ++i) cin >> tasks[i].fine;
sort(tasks, tasks + n, cmp);
bool time[505] = {false};
int total_fine = 0;
for (int i = 0; i < n; ++i) {
bool placed = false;
for (int j = tasks[i].deadline; j >= 1; --j) {
if (!time[j]) {
time[j] = true;
placed = true;
break;
}
}
if (!placed) total_fine += tasks[i].fine;
}
cout << m - total_fine << endl;
return 0;
}
```
#### 代码说明
- **时间复杂度**:$O(n^2)$(排序$O(n \log n)$ + 时间分配$O(n^2)$)
- **空间复杂度**:$O(n)$
- **关键点**:通过反向遍历时间点确保优先占用更晚的时间,为后续任务留出更多空间
阅读全文
相关推荐


















