贪心算法(Greedy Algorithm)分析

根据《算法的乐趣》阅读总结:

贪心算法每一步选择完后,局部最优解就确定了,不再进行回溯处理,也就是说,每一个步骤的局部最优解确定以后,就不再修改了,知道算法结束。因为不在进行回溯处理

贪心算法只在很少的情况下可以得到最优解,比如最短路径问题图的最小生成树问题

贪心算法的基本设计思想有三个步骤:

  1. 建立对问题精确描述的数学模型,包括定义最优解模型;
  2. 将问题分解为一系列子问题,同时定义子问题的最优解结构;
  3. 应用贪心算法原则确定每个子问题的局部最优解,并根据最优解的模型,用子问题的局部最优解堆叠出全局的最优解

背包相关问题

  1. 最优装载问题
    给出n个物体,第i个物体重量为wi。选择尽量多的物体,使得总的重量不超过C。

    —— 只关心数量,所以只需要将物体的重量排序,按照先装重量小的原则来装

  2. 部分背包问题
    有n个物体,第i个物体的重量为wi,价值为vi。在总重量不超过C的情况下让总价值尽量高。每一个物体都可以取走一部分,价值和重量按比例计算。

    ——优先拿“价值除以重量值最大的”,直到重量和为C。(由于每个物体可以只拿一部分,因此可以一定可以让总重量恰好为C(或者全部拿走重量都不满足C),而且除了最后一个物体外,要么不拿,要么全部拿走)

  3. 乘船问题
    有n个人,第i个人重量为wi,每艘船的最大载重量均为C,且最多只能乘两个人。用最少的船载所有人。

    ——最轻的人应该和选择能和他一起坐船的人中最重的一个j。首先将数据排序,用两个下标i和j表示最轻的和最重的,每次首先将j减一,找到能和j一起坐船的人,然后i加一,重复。且最后比j重的人只能一个人做一艘船了,没有最轻和他一起坐船了,此方法时间复杂度为O(n)。

区间相关问题

  1. 选择不相关区间
    数轴上有n个开区间(ai,bi)。选择尽量多的区间,使得这些区间两两没有公共点。

    ——按照bi从小到大的顺序给区间排序。贪心策略“一定要选择第一个区间。”当a1>a2选择被包含的区间(a1,b1),当(a1小于a2小于a3),还是选择(a1,b1),只有这样才能节省出更多的位置来选择更多的区间。选择了1区间后,要把和区间1相交的区间排除在外,需要记录上一个被选择的区间编号。
    贪心算法(Greedy Algorithm)分析_第1张图片

  2. 区间选点问题
    数轴上面有n个闭区间[ai,bi]。尽量选取少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)

    ——如果区间i内有一个点被取到,则称此区间被满足,首先讨论区间包含的情况,当小区间满足时,大区间也一定满足,所以在区间包含的情况下,应选择小区间。当时其他情况下是,吧所有区间按照b从小到大顺序排序(b相同时a从大到小排序),则如果出现区间包的情况,小区间一定排在前面,第一个区间应该取那个点呢?此处的贪心的策略是:取最后一个点。
    贪心算法(Greedy Algorithm)分析_第2张图片

  3. 区间覆盖问题
    数轴上有n个闭区间[ai,bi],选择尽量少的区间覆盖一条指定线段[s,t]。

    ——本题的区间仍是区间包含和排序扫描,不过要先经过一次预处理。每个区间在[s,t]外的部分都应该预先被切掉,因为他们存在是毫无意义的,预处理后,在相互包含的情况下,小区间显然不应该被考虑。把个区间按照a从小到大的排序。如果区间1的起点不是s,无解(因为其他区间的起点更大,不可能覆盖到s点),否则选择起点在s的最长区间。选择此区间[ai,bi]后,下一个区间的新的起点应该设置为bi,并且忽略所有在区间bi之前的部分,就想预处理一样,此贪心仍然只需要一次扫描,s为当前有效起点。
    贪心算法(Greedy Algorithm)分析_第3张图片

你可能感兴趣的:(算法)