GESP5级C++考试语法知识(十三、贪心算法习题:1、双向贪心 2、区间选择贪心)
第1题糖果王国的公平分配双向贪心1、 故事开场1在糖果王国里有一排小朋友站队领棒棒糖 2每个小朋友都有一个“胃口值”数字表示 胃口越大说明越想吃糖3老师要发糖果规则是1️⃣ 每个孩子至少1颗不能有人没糖 2️⃣ 如果一个孩子胃口更大他必须比旁边的人拿更多糖2、❗ 问题来了 老师想我最少要给大家分多少糖3、 为什么是“贪心算法”因为老师的策略是“我只看眼前邻居尽量给刚刚够用的糖”不多给节省糖果只满足规则局部最优 这就是贪心每一步都做“当前最省”的选择4、 举个例子13个小朋友的胃口值1 2 22 第一步先每人1颗糖糖果1 1 13 从左往右看规则右边胃口大 → 糖更多1 → 2 ✔ → 第二个要多变成1 2 1第三个2 → 2 ❌ 不需要更多4 从右往左看关键因为可能从右边看可能不满足检查2 2 不需要调整✔ 2 1 不需要调整✔保持不变1 2 1已经满足5 大家思考下如果是4个小朋友胃口值是1 3 3 1 结果会是怎样呢5、 贪心规律总结规则拆分成两个方向1️⃣ 左 → 右处理右比左大2️⃣ 右 → 左处理左比右大 每一步都只做“刚刚够”的调整6、参考程序#include iostream #include vector using namespace std; int main() { int n; cin n; vectorint a(n), candy(n, 1); for(int i 0; i n; i) cin a[i]; for(int i 1; i n; i) if(a[i] a[i-1]) candy[i] candy[i-1] 1; for(int i n-2; i 0; i--) if(a[i] a[i1]) candy[i] max(candy[i], candy[i1] 1); int sum 0; for(int x : candy) sum x; cout sum; }7、 代码逐步讲解vectorint a(n), candy(n, 1); 初始化每个人先发1颗规则1 第一轮左 → 右for(int i 1; i n; i) if(a[i] a[i-1]) candy[i] candy[i-1] 1; 含义如果右边胃口更大➡️ 糖 左边 1刚刚多一点 第二轮右 → 左for(int i n-2; i 0; i--) if(a[i] a[i1]) candy[i] max(candy[i], candy[i1] 1); 为什么要max因为左边可能已经有糖了不能变小 所以取最大 最后统计int sum 0; for(int x : candy) sum x;8、 本题本质 这是一个⭐“双向贪心 局部调整”模型 第2题时间管理大师的挑战区间贪心1、 故事开场小明报名了很多活动 活动开始结束A13B24C35但问题来了 活动不能同时参加会冲突2、❗ 目标 小明想参加最多的活动3、 为什么是贪心1小明的策略是“我优先选最早结束的活动”2为什么结束早 → 后面时间更空可以安排更多活动3 这题是典型的贪心问题4、 实例推演活动(1,3) (2,4) (3,5) 第一步按结束时间排序(1,3) (2,4) (3,5) 第二步开始选 先选 (1,3)当前结束时间 3 下一个活动(2,4) ❌ 开始2 3冲突 (3,5) ✔ 开始3 3选(3,5) 最终选了2个5、❓ 为什么不能选“开始最早”反例(1,10), (2,3), (3,4)如果选 (1,10) 后面全没了 ❌正确做法 选结束早的6、 贪心规律总结1按结束时间排序2 每次选开始时间 ≥ 当前结束时间7、 代码逐步讲解#include iostream #include algorithm using namespace std; struct Node { int l, r; }; bool cmp(Node a, Node b) { return a.r b.r; } int main() { int n; cin n; Node a[1005]; for(int i 0; i n; i) cin a[i].l a[i].r; sort(a, a n, cmp); int cnt 0, last -1e9; for(int i 0; i n; i) { if(a[i].l last) { cnt; last a[i].r; } } cout cnt; }8、 代码逐步讲解1 结构体struct Node { int l, r; }; l 开始 r 结束2 排序sort(a, a n, cmp);bool cmp(Node a, Node b) { return a.r b.r; } 按结束时间升序3 贪心选择int cnt 0, last -1e9; last 上一个活动结束时间for(int i 0; i n; i) { if(a[i].l last) { cnt; last a[i].r; } } 逻辑如果不冲突 → 选更新结束时间9、 本题本质 这是一个⭐“区间选择贪心按结束时间排序”经典模型 两题对比总结非常关键题目贪心策略本质 糖果局部最小调整双向贪心 活动选结束最早区间贪心
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2589833.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!