信友队智灵班提高基础班2025.7.12日学习笔记+总结

算法:贪心法

贪心思想/贪心策略

对于组合最优化问题,可以按照一定简单策略逐步得到最优解

组合最优化问题

泛指寻求一个最优组合对象的问题。


证明贪心策略正确性

要证明一个贪心策略的正确性,只需要证明最优解的第一步包含贪心策略的决策


贪心常用方法

  • 想要贪心,常常需要我们对原序列排序,使其满足单调递增/不减/递减/不增性,便于我们逐步求解。
  • 对于一类区间贪心问题,我们需要对左端点/右端点进行排序,然后通过枚举/优先队列/二分等方法来优化并找到答案。
  • 对于一部分难以逐步求最优解的问题,我们可以先进行一种决策,然后如果发现不是最优,用一些数据结构进行反悔

贪心错误经验

  • 对于大部分贪心题目,基本上会让你有一个立刻就能想到但必错的贪心策略,所以一定要多思考。
  • 验证贪心的过程中,首先要找反例,否则很可能会找到一个爆零的策略。

经典例题

小木棍

题目大意: 给你 \(n\) 根火柴棒,要求摆成指定形状的数字,使得火柴棒全部用完且数字最小。
思路分析: 这一题其实容易想到,要想要一个数字最小,首先要使得它的位数最小,其次要让首位最小,再次要让第二位最小……那么,想让一个数的位数最少,肯定要是每一位需要的火柴棒尽量多,也就是多摆8。摆8需要7根火柴棒,所以可能会剩余 \(n\mod 7\) 根火柴棒。对于每一种余数,我们单独讨论:
0. 肯定是摆888...

  1. 如果 \(n=1\) ,那么无解;如果 \(n\ge 8\) ,那么摆10888...
  2. 可以摆 2888...
  3. 如果 \(n=3\) ,那么摆7;如果\(n=10\),那么摆22;如果\(n=17\),那么摆20;如果 \(n>17\) ,那么摆 20888...
  4. 如果 \(n=4\),那么摆 4;如果 \(n\ge 11\),那么摆20888...
  5. 如果 \(n=5\),那么摆2;如果 \(n\ge 12\) ,那么摆2888...
  6. 如果 \(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\) 元最多能买几个商品。

\[\begin{matrix} 1\le n\le 50000 \\ 1\le m\le 10^{14} \\ 1\le C_i \le P_i\le 10^9 \\ m、P_i和C_i都是整数 \end{matrix} \]

思路分析: 这一题我们优先考虑买 \(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\) 是当前的优惠券加上前面的优惠券去掉后补回的差价),这样就能计算需要的花费了。

posted @ 2025-07-13 07:26  c_haoc  阅读(39)  评论(0)    收藏  举报