Initial commit: C++ courseware

This commit is contained in:
xiaolinquan committed 2026-11-05 22:51:02 +08:00
commit 4a4ee7c287
1789 files changed
+373489

No files matched your search

@@ -0,0 +1,33 @@
### **参考答案**
#### **一、 填空题**
1. 局部最优,全局最优解
2. 无后效性
3. 价值密度(或 性价比)
4. 比较函数
5. 最优子结构
#### **二、 单项选择题**
1. B
2. C
3. C
4. B
5. B
6. D
7. C
8. C
9. C
10. A
#### **三、 判断题**
1. ×
2. √
3. √
4. ×
5. √
6. √
7. √
8. × (对于部分背包问题,该物品可以装入一部分)
9. × (通常时间复杂度更低)
10. √
@@ -0,0 +1,70 @@
### C++ 贪心算法(上) 课后习题
姓名: ____________________________________________
#### **一、 填空题**
1. 贪心算法在求解问题的每一步中,都做出一个 **\_\_\_\_\_\_\_\_\_\_** 的选择,寄希望于一系列的局部最优选择能够产生一个 **\_\_\_\_\_\_\_\_\_\_**。
2. 一个问题能用贪心算法求解,通常需要满足 **\_\_\_\_\_\_\_\_\_\_** 和最优子结构两个关键性质。
3. 在部分背包问题中,正确的贪心标准是优先选择 **\_\_\_\_\_\_\_\_\_\_** 最高的物品。
4. 在C++代码实现中,为了对物品按价值密度进行排序,我们可以使用`sort`函数,并为其提供一个自定义的 **\_\_\_\_\_\_\_\_\_\_**。
5. 一个问题的最优解包含了其子问题的最优解,这个性质被称为 **\_\_\_\_\_\_\_\_\_\_**。
#### **二、 单项选择题**
( ) 1. 贪心算法的核心思想是?
A. 穷举所有可能 B. 每步都做出局部最优选择 C. 将问题分解为不相关的子问题 D. 从后向前推导最终解
( ) 2. 根据讲义,以下哪个问题是适合用贪心算法解决的典型例子?
A. 0-1背包问题 B. 排序问题 C. 部分背包问题 D. 二分问题
( ) 3. 对于部分背包问题,最佳的贪心策略是?
A. 优先选择价值最高的物品 B. 优先选择重量最轻的物品 C. 优先选择价值密度最高的物品 D. 随机选择物品
( ) 4. “某个状态以前的过程不会影响以后的状态,只与当前状态有关”描述的是贪心算法的哪个性质?
A. 最优子结构 B. 无后效性 C. 高效性 D. 启发性
( ) 5. 假设背包容量为20,有A、B两个物品。A重10价值60,B重20价值100。按照部分背包问题(可拆分物品)的贪心策略,最终得到的最大价值是?
A. 120 B. 110 C. 100 D. 60
( ) 6. 在部分背包问题的C++代码实现中,`Item`结构体中的`ratio`(价值密度/性价比)成员最好使用什么类型?
A. `int` B. `char` C. `bool` D. `double`
( ) 7. 已知`Item`结构体内有三个成员变量分别为:`v`: 物品价值, `m`: 物品重量, `ratio`: 物品价值密度, 在对物品按价值密度进行降序排序时,自定义比较函数`bool cmp(const Item& a, const Item& b)`的正确写法是?
A. `return a.v > b.v;` B. `return a.m < b.m;` C. `return a.ratio > b.ratio;` D. `return a.ratio < b.ratio;`
( ) 8. 一个贪心策略通常可以使用什么办法来证明?
A. 公式法 B. 暴力枚举法 C. 反证法 D. 数学归纳法
( ) 9. 在处理最后一个无法完全装入的物品时,应该如何计算其贡献的价值?
A. 计为0 B. 计为其全部价值 C. (剩余容量 / 物品重量) \* 物品价值 D. 无法计算
( ) 10. 为什么“优先选择价值最高的物品”的策略对于部分背包问题是错误的?
A. 因为它忽略了物品的重量 B. 因为它忽略了背包的容量 C. 因为价值最高的物品总是最重 D. 因为该策略计算过于复杂
#### **三、 判断题 (对的打“√”,错的打“×”)**
( ) 1. 贪心算法适用于所有最优化问题,并且总能找到最优解。
( ) 2. 对于部分背包问题,我们可以将物品分割成任意大小的块装入背包。
( ) 3. 在贪心算法中,一旦一个选择被做出,它就不会被撤销或更改。
( ) 4. “重量最轻优先”是解决部分背包问题的一个有效贪心策略。
( ) 5. 贪心算法就算得不到最优解,也能够快速给出一个质量较高的可行解。
( ) 6. 贪心算法的正确性通常需要严格的数学证明,不能仅凭直觉。
( ) 7. 在C++代码中,`sort(items.begin(), items.end(), cmp);` 这行代码实现了贪心策略的核心部分,即对物品进行排序。
( ) 8. 如果一个物品的重量大于当前背包的剩余容量,那么该物品以及之后的所有物品都不能再装入背包。
( ) 9. 贪心算法相较于暴力搜索算法,通常具有更高的时间复杂度。
( ) 10. 在计算价值密度时,`ratio = (double)v / m;` 是为了防止整数除法导致精度丢失。
@@ -0,0 +1,31 @@
### **参考答案**
#### **一、 填空题**
1. 合并
2. 权值最小
3. Q1的队头,Q2的队头
4. 频率
5. 两堆果子的重量(或权值)之和
#### **二、 单项选择题**
1. B
2. B
3. C (先合并10和20,成本30,新堆为30。再合并两个30,成本60。总成本30+60=90)
4. B (因为后合并的权值更大,放队尾可维持Q2有序)
5. B
7. B
8. D (活动安排属于区间选择贪心模型)
9. C
10. C
#### **三、 判断题**
1. × (讲义中{30,30,30,30}的例子说明对半分更好,但{10,20,30,40}的例子说明分离最大更好,证明单一策略不是普适的)
2. √
3. × (应该尽可能晚地参与合并)
4. √
5. × (不一定,全局最小值在两个队头之一,但无法保证Q1队头一定小于Q2队头)
6. × (可以调整,变为每次合并权值最小的`k`个)
7. √ (这是前缀码的定义,也是哈夫曼编码的性质)
8. √
9. √ (每次操作的成本是被分的那一摞卷子的总数量,总成本是所有操作成本之和)
@@ -0,0 +1,61 @@
### C++ 贪心算法(下) 课后习题
姓名: ____________________________________________
#### **一、 填空题**
1. 通过逆向思维,分卷子的拆分问题可以转化为转化为等价的\_\_\_\_\_\_\_\_\_\_问题来求解。
2. 有 n 个元素带权,二合一合并求最小总成本的问题叫做霍夫曼模型,其最优贪心策略是:每一次操作,都选择当前所有元素中 **\_\_\_\_\_\_\_\_\_\_** 的两个进行合并。
3. 在使用双队列法(两个队列的变量名为`Q1` 和 `Q2`)实现霍夫曼模型时,全局最小的元素只可能出现在 **\_\_\_\_\_\_\_\_\_\_** 或 **\_\_\_\_\_\_\_\_\_\_**。
#### **二、 单项选择题**
( ) 1. “分卷子”的例子告诉我们,正向思考“每次分离出最大的一堆”这个贪心策略是?
A. 正确的 B. 错误的 C. 最低效的 D. 最高效的
( ) 2. 对于“合并果子”问题,正确的贪心策略是?
A. 优先合并重量最大的两堆 B. 优先合并重量最轻的两堆 C. 优先合并重量最接近的两堆 D. 随机合并
( ) 3. 有三堆果子,重量分别为 10, 20, 30。将它们合并成一堆的最小总成本是?
A. 60 B. 80 C. 90 D. 110
( ) 4. 在双队列法中,我们将合并后新产生的元素放入第二个队列(Q2)的哪个位置?
A. 队头 B. 队尾 C. 任意位置 D. 替换队头
( ) 5. 双队列法能够高效实现霍夫曼模型,其关键是?
A. 两个队列的长度永远相等 B. 新产生的元素组成的队列Q2自然有序
​ C. Q1队列的元素会越来越少 D. 只需要一个队列就够了
( ) 6. 哈夫曼编码的目标是使得编码后的信息总长度最小,它通过什么方式实现?
A. 让所有字符编码等长 B. 出现频率高的字符编码短,频率低的编码长
​ C. 出现频率低的字符编码短,频率高的编码长 D. 使用尽可能多的0
( ) 7. 下列哪个问题不适合直接用霍夫曼模型解决?
A. 合并N堆石子,成本为合并后石子总数 B. 构建哈夫曼编码
​ C. 分离试卷,成本为分离前试卷总数 D. 活动安排问题
( ) 8. 在双队列法的`get_min`函数中,如果Q1为空,应该从哪里取元素?
A. 无法继续 B. 从Q1队尾 C. 从Q2队头 D. 随机选择
( ) 9. “分卷子”问题和“哈夫曼编码”的构建过程,都体现了哪种重要的算法思想?
A. 分治思想 B. 动态规划 C. 逆向思维与贪心 D. 暴力搜索
#### **三、 判断题 (对的打“√”,错的打“×”)**
( ) 1. 对于任意输入的果子重量,“每次对半分”的合并策略总能得到最小成本。
( ) 2. “从上往下”拆分的最小成本,等于“从下往上”合并的最小成本。
( ) 3. 在“合并果子”问题中,一个重量较大的果子堆,应该尽早参与合并,以减小总成本。
( ) 4. 在双队列法中,因为新合并的果子堆是放入Q2的,所以Q1中的元素数量只减不增。
( ) 5. 在任意时刻,Q1队头的元素一定小于等于Q2队头的元素。
( ) 6. 霍夫曼模型的核心是“二合一”操作,如果每次可以合并三堆,则不能使用类似的贪心思想。
( ) 7. 哈夫曼编码是一种前缀码,意味着任何一个字符的编码都不是另一个字符编码的前缀。
( ) 8. 双队列法的核心是避免了重复排序,从而提高了算法效率。
( ) 9. 在“分卷子”问题中,总成本等于所有中间步骤产生的卷子堆的数量之和。
@@ -0,0 +1,28 @@
### C++ 贪心算法(中) 课后习题 - **答案**
#### **一、 填空题**
1. 总等待时间
2. 权重,短
3. 结束时间
4. 不相交 (或 不重叠)
5. 右端点
6. 价值密度 (或 性价比)
7. 反证法
#### **二、 单项选择题**
1. B 2. A 3. C 4. C 5. B 6. B 7. C 8. D 9. C 10. A
#### **三、 判断题**
1. √
2. × (这是一个常见的错误贪心策略,反例:活动(1,10), (2,3), (4,5)。选(1,10)后其他都不能选,但选(2,3)和(4,5)更优。)
3. √
4. √
5. × (“0-1背包”问题不能用简单的贪心策略解决,是动态规划的经典问题。)
6. √
7. √
8. × (目标是区间的**数量**最多,而不是总长度最长。)
9. × (贪心算法只对具有特定性质的问题能找到最优解,对很多问题只能找到近似解或不可行。)
10. √
@@ -0,0 +1,70 @@
### C++ 贪心算法(中) 课后习题
姓名: \_\_\_\_\_\_\_\_\_\_\_\_\_
#### **一、 填空题**
1. 在“排队接水”问题中,我们的目标是让所有人的平均等待时间最小,这等价于让所有人的\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_之和最小。
2. 在“排队接水”问题总等待时间的计算公式中,排在越前面的人,其接水时间所乘的\_\_\_\_\_\_\_\_\_\_\_\_\_越大。因此,我们的贪心策略是让接水时间\_\_\_\_\_\_\_\_\_\_\_\_\_的人排在最前面。
3. “活动安排”问题的贪心策略是:将所有活动按\_\_\_\_\_\_\_\_\_\_\_\_\_从小到大排序,然后依次选择与已选活动不冲突的活动。
4. “活动安排”问题可以被抽象为更普适的数学模型,叫做“最多\_\_\_\_\_\_\_\_\_\_\_\_\_区间问题”。
5. 在“射气球”或“区间选点”问题中,我们通常将所有区间按\_\_\_\_\_\_\_\_\_\_\_\_\_从小到大排序。
6. 对于部分背包问题(有n个不同价值,不同重量物品可供选择,每个物品可分割,求在一定背包容量下能获取的物品的最大价值),它的贪心标准是优先选择\_\_\_\_\_\_\_\_\_\_\_\_\_最高的物品。
7. 我们常用\_\_\_\_\_\_\_\_\_\_\_\_\_来证明一个贪心策略的正确性。
#### **二、 单项选择题**
( ) 1. 在“排队接水”问题中,正确的排队策略是什么?
A. 接水时间长的人排在前面
B. 接水时间短的人排在前面
C. 随机排队
D. 按到达顺序排队
( ) 2. 假设有4个人排队接水,他们的接水时间分别是 $t_1, t_2, t_3, t_4$。在总等待时间的计算公式中,哪个人的接水时间被计算的次数最多?
A. 第1个人($t_1$) B. 第2个人($t_2$) C. 第3个人($t_3$) D. 第4个人($t_4$)
( ) 3. 有3个人排队接水,时间分别是 2分钟、5分钟、8分钟。要使总等待时间最短,他们的排队顺序应该是?
A. `8, 5, 2` B. `5, 8, 2` C. `2, 5, 8` D. 任意顺序都可以
( ) 4. 在一个大量有时间冲突的活动中,要求选择出**数量最多**的、互不冲突的活动问题中,正确的贪心策略是?
A. 优先选择开始时间最早的活动
B. 优先选择持续时间最短的活动
C. 优先选择结束时间最早的活动
D. 优先选择开始时间最晚的活动
( ) 5. 在一个大量有时间冲突的活动中,要求选择出**数量最多**的、互不冲突的活动问题中,采取“结束时间最早”策略的主要理由是?
A. 让每个活动尽快开始
B. 尽快结束当前活动,为未来留下最大的选择空间
C. 确保持续时间长的活动能被安排
D. 避免活动之间有任何空闲时间
( ) 6. 考虑以下活动(开始时间, 结束时间):A(1, 4), B(3, 5), C(0, 6), D(5, 7)。按照“活动安排”的贪心策略,最多能选出几个活动?
A. 1 B. 2 C. 3 D. 4
( ) 7. 对于射气球问题:在 X 轴上,有一些水平方向的气球。每个气球可以由一个开始和结束坐标去表示,要求用最少的箭射爆所有气球,它的贪心策略是?
A. 按气球宽度从大到小排序
B. 按气球左端点从小到大排序
C. 按气球右端点从小到大排序
D. 随机选择一个气球射击
( ) 8. 现有A, B, C, D四个活动,它们的起止时间分别是A(8, 11), B(9, 12), C(10, 13), D(8, 10)。为了能安排下尽可能多的活动,根据贪心策略,我们应该首先选择哪个活动?
A. 活动A B. 活动B C. 活动C D. 活动D
( ) 9. 部分背包问题,其贪心选择能够成立的关键前提是?
A. 物品价值都很高 B. 物品重量都很轻
C. 物品可以被任意分割 D. 背包容量非常大
( ) 10. 一个问题能用贪心算法求解,通常需要满足最优子结构和什么性质?
A. 无后效性 B. 先进先出 C. 后进先出 D. 运行速度快
#### **三、 判断题 (对的打“√”,错的打“×”)**
( ) 1. 在“排队接水”问题中,让接水时间最长的人排在队尾,总等待时间会最短。
( ) 2. 在“活动安排”问题中,总是优先选择开始时间最早的活动,一定能得到最优解。
( ) 3. 贪心算法在每一步都做出一个当前看起来最好的选择。
( ) 4. 在“射气球”问题中,按右端点排序后,第一支箭应该射在第一个气球的右端点位置。
( ) 5. “部分背包”问题和“0-1背包”问题(物品不能分割)都可以用相同的贪心策略解决。
( ) 6. 学习贪心算法的关键在于识别问题的内在数学模型,并找到正确的贪心标准。
( ) 7. 在“排队接水”问题中,即使所有人的接水时间都一样,交换任意两个人的位置,总等待时间也不会改变。
( ) 8. 在“最多不相交区间问题”中,我们的目标是让选出的所有区间的总长度最长。
( ) 9. 贪心算法总能为所有问题找到全局最优解。
( ) 10. “排队接水”和“活动安排”两个问题的贪心策略,第一步都是对输入数据进行排序。