《Python算法竞赛攻略:从入门到降维打击》——第四章

第四章:基础算法思想

欢迎来到“通用剑法篇”。如果说第一部分“基础心法篇”我们修炼的是内力,武装了Python这把神兵利器,那么从本章开始,我们将正式学习具体的“剑法招式”。这些招式——贪心、模拟、枚举、递推与分治——是算法世界中最普适、最基础的思想,也是构成更复杂算法的“基本功”。

掌握好这些基础算法思想,你将能够解决大部分普及组难度的题目,并为后续学习动态规划、图论等高阶算法打下坚实的基础。在本章,我们将彻底贯彻本书的核心理念:用最Pythonic的方式,去理解和实现这些经典算法思想。


4.1 贪心 (Greedy):局部最优解的智慧

贪心算法,顾名思义,就是“贪婪地”做出选择。在面临一个需要多步决策的问题时,它在每一步都选择当前看起来最好、最优的选项,寄希望于一系列的局部最优解能够最终导向全局最优解。

这是一种简单、高效的思想,但它并不总是正确的。使用贪心算法的诀窍在于判断“局部最优”是否真的能推出“全局最优”。这个证明过程在算法竞赛中我们往往会选择性地忽略,更多是依靠直觉、经验或者题目的暗示(例如,数据范围暗示了只能使用低复杂度的算法)。

核心思想:

  1. 建立评价标准: 确定一个标准,用于衡量每一步决策的“好坏”(例如,价值最大、耗时最少、结束时间最早等)。
  2. 循环决策: 在一个循环中,或通过排序,不断地根据评价标准做出当前最优的选择。
  3. 组合解: 将每一步的局部最优选择组合起来,形成问题的最终解。

【实战场景1:活动安排问题】

这是一个经典的贪心算法应用场景。

  • 问题描述: 假设有n个活动,每个活动都有一个开始时间 sis_isi 和一个结束时间 fif_ifi。你只有一个会议室,问最多可以安排多少个活动,使得这些活动的时间不冲突。

  • 思路分析: 如何选择才是“贪心”的?

    • 选择开始最早的? 反例:一个开始很早但持续时间很长的活动,可能会“锁死”会议室,导致错过多个持续时间短的活动。
    • 选择持续时间最短的? 反例:一个持续时间很短但恰好在两个长时间活动之间的活动,选择它可能会导致错过那两个活动。
    • 正确的贪心策略:选择结束时间最早的活动。 为什么?因为选择结束时间最早的活动,可以尽快地释放会议室资源,为后续安排更多的活动提供可能性。这确保了局部最优(尽快结束)能够导向全局最优(安排活动最多)。
  • Pythonic实现:
    在Python中,这个策略的实现极其优雅。我们只需要将所有活动存入一个列表,然后根据每个活动的结束时间进行排序即可。

    def schedule_activities(activities):
        """
        解决活动安排问题
        :param activities: 一个列表,每个元素是形如 (start_time, end_time) 的元组
        :return: 最多可以安排的活动数量
        """
        if not activities:
            return 0
    
        # 核心:按活动的结束时间升序排序
        # a[1] 代表元组的第二个元素,即结束时间
        activities.sort(key=lambda a: a[1])
    
        count = 1  # 第一个活动(结束时间最早的)必定入选
        last_end_time = activities[0][1]
    
        # 遍历剩余的活动
        for i in range(1, len(activities)):
            current_start_time = activities[i][0]
            # 如果当前活动的开始时间晚于或等于上一个已安排活动的结束时间
            # 说明不冲突,可以安排
            if current_start_time >= last_end_time:
                count += 1
                last_end_time = activities[i][1]
    
        return count
    
    # --- 示例 ---
    # 活动列表:[(开始时间, 结束时间), ...]
    acts = [(1, 4), (3, 5), (0, 6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱看烟花的码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值