C++实现简单贪心算法 _ 区间调度问题与最优解法【源码】

风杰酱_1106

风杰酱_1106

2026-04-11

750人浏览

原创

按结束时间升序排序才能得到最优解,因为早结束的区间为后续留出更多选择空间,数学上可证该贪心策略不劣于任意最优解;按开始时间排序或不排序会导致局部最优却全局次优。

c++实现简单贪心算法 _ 区间调度问题与最优解法【源码】

为什么按结束时间排序才能得到最优解

区间调度问题里,贪心策略的核心不是“选最长的”或“选最早的”,而是按结束时间升序排序后每次选当前可选中结束最早的区间。这是因为早结束给后续留出更多空间,数学上能证明该策略不会比任意最优解差——任何其他选择都可以被替换成这个更早结束的而不减少总数。

常见错误是按开始时间排序,结果可能卡死在某个长区间上,后面一堆短区间全被排除;或者不排序直接遍历,完全失去贪心前提。

  • 必须用 std::sort 配合自定义比较函数,不能只靠 std::vector::sort 默认行为
  • 比较函数要写成 [&](const auto& a, const auto& b) { return a[1] ,索引 <code>1 是结束时间(假设每个区间是 {start, end})
  • 如果输入含闭区间且端点重叠(如 [1,3] 和 [3,5]),需明确是否允许相接:允许就用 last_end ,否则用 <code>last_end

如何用 vector> 存储并避免越界访问

用 std::vector<:pair int>></:pair> 存区间最直观,first 是开始,second 是结束。但注意:C++ 中 pair 的成员名固定,别写成 .start 或 .end——那会编译失败。

实际编码时容易在循环中多取一个元素,比如用 i 却在循环体里访问 <code>intervals[i+1],导致越界。安全做法是初始化 count = 1、last_end = intervals[0].second,然后从 i = 1 开始遍历。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 声明时写 vector<pair int>> intervals;</pair>,读入后立刻检查 if (intervals.empty()) return 0;
  • 排序前确认每个 pair 满足 a.first ,否则 <code>sort 后逻辑错乱
  • 不要用 auto& p : intervals 范围 for 做贪心选择——你得跳过不满足条件的,无法用简单遍历替代索引控制

完整可运行代码的关键三步

一个能直接编译运行的最小实现,核心就三步:输入解析 → 排序 → 贪心扫描。没有类封装、不引入额外结构,适合调试和验证逻辑。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int n; cin >> n;
    vector<pair int>> intervals;
    for (int i = 0; i > s >> e;
        intervals.emplace_back(s, e);
    }
    if (intervals.empty()) { cout = last_end) { // 允许端点相接用 >=,严格不交用 >
            ++count;
            last_end = intervals[i].second;
        }
    }
    cout 
<p>注意 <code>intervals[i].first >= last_end</code> 这行:很多题要求“不重叠”,但数学定义中 <code>[1,3]</code> 和 <code>[3,5]</code> 是 disjoint 的,是否接受取决于题目描述——漏看这点会导致样例通过但评测 WA。</p>

<h3>扩展到带权重的加权区间调度怎么办</h3>
<p>原题是“最多选几个”,属于无权版本;一旦每个区间带权重(如价值、优先级),贪心失效,必须转为动态规划。此时 <code>sort</code> 仍按结束时间,但状态转移变成:对每个区间 <code>i</code>,找最后一个满足 <code>end[j]  的 <code>j</code>,然后 <code>dp[i] = max(dp[i-1], dp[j] + weight[i])</code>。</code></p>
<p>这里最容易忽略的是查找 <code>j</code> 的效率——暴力扫是 O(n²),用 <code>upper_bound</code> 配合预存的结束时间数组可压到 O(n log n)。但前提是结束时间数组已排序(恰好就是我们排好的),所以别在 DP 里再排一遍。</p>
<ul>
<li>别试图用贪心“加个权重修正”来应付加权版——不存在通用修正公式</li>
<li>
<code>std::upper_bound</code> 查的是第一个 > target 的位置,要找 ≤ target 的最后一个,得用 <code>std::prev(upper_bound(...))</code>
</li>
<li>DP 数组长度必须是 <code>n+1</code>,留出 <code>dp[0] = 0</code> 边界,否则 <code>j = -1</code> 时难处理</li>
</ul>

贪心成立的前提非常具体:目标函数是计数型、约束是区间不交、收益无差异。换掉其中任一条件,就得重新评估策略。实际写题时,先盯死题目问的是“最多几个”还是“最大总权重”,这决定你是写 5 行还是 20 行。</pair></algorithm></vector></iostream>

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

2023.09.04

1138

7

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2178

7

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5707

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2468

6

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

2023.08.14

5816

4

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

2026.10.16

0

10

OpenJDK怎么配置Java开发环境
OpenJDK怎么配置Java开发环境

怎样用OpenJDK搭建开发环境?本专题介绍版本选择、下载安装、环境变量配置和编译运行验证,帮助你理清JDK的作用及基本配置流程,并通过简单程序检查环境是否可用,为后续项目开发做好准备。

2026.10.16

0

10

OpenJDK怎么部署Java应用
OpenJDK怎么部署Java应用

Java项目开发完成后,怎样部署到目标环境并正常运行?本专题介绍OpenJDK应用部署流程,涵盖运行环境准备、版本兼容检查、应用打包、启动参数配置和日志查看,帮助你理清部署前后的操作顺序,减少环境差异造成的运行问题。

2026.10.16

0

10

Revel框架模板渲染与表单验证
Revel框架模板渲染与表单验证

本专题围绕Revel框架视图层开发,介绍模板语法、变量输出、布局复用、表单提交、参数绑定与验证规则,帮助开发者完成安全规范的页面交互。

2026.10.16

0

15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习