信友队智灵班提高基础班2025.7.12日学习笔记+总结
算法:贪心法
贪心思想/贪心策略
对于组合最优化问题,可以按照一定简单策略,逐步得到最优解。
组合最优化问题
泛指寻求一个最优组合对象的问题。
证明贪心策略正确性
要证明一个贪心策略的正确性,只需要证明最优解的第一步包含贪心策略的决策。
贪心常用方法
- 想要贪心,常常需要我们对原序列排序,使其满足单调递增/不减/递减/不增性,便于我们逐步求解。
- 对于一类区间贪心问题,我们需要对左端点/右端点进行排序,然后通过枚举/优先队列/二分等方法来优化并找到答案。
- 对于一部分难以逐步求最优解的问题,我们可以先进行一种决策,然后如果发现不是最优,用一些数据结构进行反悔。
贪心错误经验
- 对于大部分贪心题目,基本上会让你有一个立刻就能想到但必错的贪心策略,所以一定要多思考。
- 验证贪心的过程中,首先要找反例,否则很可能会找到一个爆零的策略。
经典例题
小木棍
题目大意: 给你 \(n\) 根火柴棒,要求摆成指定形状的数字,使得火柴棒全部用完且数字最小。
思路分析: 这一题其实容易想到,要想要一个数字最小,首先要使得它的位数最小,其次要让首位最小,再次要让第二位最小……那么,想让一个数的位数最少,肯定要是每一位需要的火柴棒尽量多,也就是多摆8。摆8需要7根火柴棒,所以可能会剩余 \(n\mod 7\) 根火柴棒。对于每一种余数,我们单独讨论:
0. 肯定是摆888...
- 如果 \(n=1\) ,那么无解;如果 \(n\ge 8\) ,那么摆
10888...。 - 可以摆
2888... - 如果 \(n=3\) ,那么摆
7;如果\(n=10\),那么摆22;如果\(n=17\),那么摆20;如果 \(n>17\) ,那么摆20888...。 - 如果 \(n=4\),那么摆
4;如果 \(n\ge 11\),那么摆20888...。 - 如果 \(n=5\),那么摆
2;如果 \(n\ge 12\) ,那么摆2888...。 - 如果 \(n=6\),那么摆
6;如果 \(n\ge 13\),那么摆6888...。
从中能注意到,我们还需要特判 \(n\le 17\) 的情况。本题的难点在于多组测试数据的严格,让你不能失误。
廊桥分配
题目大意: 给你 \(n\) 个廊桥、 \(m_1\) 个国内航班和 \(m_2\) 个国际航班。每个航班由到达时间 \(s\) 和离开时间 \(e\) 组成。航班占据廊桥依照先到先得规则,会占据直到离开廊桥。每个廊桥可以只给国内航班使用或只给国际航班使用。求最多有几个航班能占据廊桥。
思路分析: 这一题有点难办。我们可以先记录国内和国际航班各使用 \(x\le n\) 个廊桥的最多航班并求前缀和,再枚举国内航班的廊桥数,求最大值。
现在我们的问题转化成了:给定 \(n\) 个廊桥,请求出 \(1\le x\le n\) 个廊桥最多能迎接几个航班。
这时,我们可以想到:\(n\) 个廊桥,其实就是 \(n\) 个区间组数。求这些区间在 \(1\le x\le n\) 个分组最多几个航班。 现在就好求了。
奶牛优惠券
题目大意: 给你 \(n\) 个商品和 \(k\) 张优惠券。第 \(i\) 个商品原价 \(P_i\) ,使用优惠券后的价格是 \(C_i\) 。求 \(m\) 元最多能买几个商品。
思路分析: 这一题我们优先考虑买 \(C_i\) 前 \(k\) 小的商品,然后设差价 \(\Delta _i\) 为 \(P_i - C_i\) 。这个时候我们遍历没有买的物品,同时用优先队列维护第 \(k\) 小的 \(\Delta _k\) 。这个时候我们如何判断剩下的商品够不够买呢?我们可以求一个 \(\min (P_i,C_i+\Delta _k)\) (\(i\) 是当前判断的商品,\(P_i\) 是当前价格,\(C_i+\Delta _k\) 是当前的优惠券加上前面的优惠券去掉后补回的差价),这样就能计算需要的花费了。

浙公网安备 33010602011771号