第二章老师带着我们学习了分治算法,在学习分治算法的过程中,我不禁联想到了动态规划法和贪心算法。
分治法,动态规划法,贪心算法这三者之间有类似之处,比如都需要将问题划分为一个个子问题,然后通过解决这些子问题来解决最终问题。我对这三种算法的不同和类似之处产生了很大的兴趣。
分治法是指将问题划分成一些独立的子问题,递归的求解各子问题,然后合并子问题的解而得到原问题的解。与此不同,动态规划适用于子问题独立且重叠的情况,也就是各子问题包含公共的子子问题。在这种情况下,若用分治法则会做许多不必要的工作,即重复地求解公共的子问题。动态规划算法对每个子子问题只求解一次,将其结果保存在一张表中,也就是“备忘录”,从而避免每次遇到各个子问题时重新计算答案。
贪心算法与动态规划与很多相似之处。特别地,贪心算法适用的问题也是最优子结构。贪心算法与动态规划有一个显著的区别,就是贪心算法中,是以自顶向下的方式使用最优子结构的。贪心算法会先做选择,在当时看起来是最优的选择,然后再求解一个结果子问题,而不是先寻找子问题的最优解,然后再做选择。
学习第二章的过程中,老师让我们结对编程,做了pta上的最大子列和问题和找第k小的数的题目。
最大子列和:利用分治算法的思想,将找最大子列和问题分成了“找边界左边最大子列和”,“找边界左边最大子列和”和“找跨越边界最大子列和”这三个小问题,并对“找边界左边最大子列和”,“找边界左边最大子列和”这两个小问题进行递归求解,最后对递归最顶层的“找边界左边最大子列和”,“找边界左边最大子列和”和“找跨越边界最大子列和”这三个结果进行比较,返回最大的值。
代码略。
找第k小的数:这个问题可以看成是快速排序的变形。而快速排序本质就是分治算法的思想:随机找出一个数,可以随机取,也可以取固定位置,一般是取第一个或最后一个称为基准,然后就是比基准小的放在左边,比基准大的放到右边。如何放呢?就是和基准进行交换,这样交换完左边都是比基准小的,右边都是比较基准大的,这样就将一个数组分成了两个子数组,然后再按照同样的方法把子数组再分成更小的子数组,直到不能分解为止。
代码略。
在做这些题目的时候都用到递归求解。而在做递归求解时主要有三个步骤:
1.定义递归函数的作用,即该函数主要做什么?
2.找到函数结束的条件.
3.找到问题转化为若干个子问题的方程.
如2-3 蜜蜂路线 (20分)中,1.定义递归函数routes(int number)的作用就是求从蜂房a爬到离蜂房a距离为number的蜂房b的可能路线数 。2.很明显当number = 1/2,函数就要结束,返回确定值。3.routes(n) = routes(n-1)+routes(n-2)
这次结对编程过程中,我和组员互相交流,在给组员讲解他不懂的地方时,我对分治算法的理解更深一层。
原文地址:https://www.cnblogs.com/whitewater/p/13774093.html