题解(贪心)
2026-09-17 21:56:14
发布于:湖南
1阅读
0回复
0点赞
思路:
这是一道经典的区间调度 贪心问题。因为班车只能沿直线跑一次,且每个小组的行程是区间,我们需要选择尽可能多的奶牛上车,使得在任意时刻,车上奶牛数不超过容量 。
贪心策略:
1.
将所有小组按终点 从小到大排序(若终点相同,则按起点从大到小)。
2.
依次处理每个小组,检查当前区间内每个站点已有的奶牛数是否都。
若是,则尽可能多地安排该组奶牛上车(即填满容量),并更新区间内的占用数。
若否,则跳过该组(或部分安排,但贪心已保证最优)。
注意:因为允许部分奶牛分开乘坐,所以每组可以只上部分奶牛。但贪心按终点排序后,能放就放满是最优的。
正确性:
按终点排序后,先处理早结束的区间,能最大化后续区间的可用容量,这是经典的区间调度贪心。
代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Group {
int s, e, m;
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int K, N, C;
cin >> K >> N >> C;
vector<Group> groups(K);
for (auto &g : groups) {
cin >> g.s >> g.e >> g.m;
}
// 按终点从小到大排序,若终点相同则按起点从大到小
sort(groups.begin(), groups.end(), [](const Group &a, const Group &b) {
if (a.e != b.e) return a.e < b.e;
return a.s > b.s;
});
vector<int> load(N + 1, 0); // load[i] 表示站点 i 到 i+1 之间的车上奶牛数
int ans = 0;
for (auto &g : groups) {
// 找到区间 [s, e) 内的最大负载
int maxLoad = 0;
for (int i = g.s; i < g.e; i++) {
maxLoad = max(maxLoad, load[i]);
}
int canTake = min(g.m, C - maxLoad);
if (canTake > 0) {
for (int i = g.s; i < g.e; i++) {
load[i] += canTake;
}
ans += canTake;
}
}
cout << ans << "\n";
return 0;
}
这里空空如也





有帮助,赞一个