zoukankan      html  css  js  c++  java
  • 分治与递归

    分治法的基本思想:将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解这些问题,然后将各个子问题的解合并成原问题的解。它的一般的算法设计模式如下:

    divide-and-conquer(P)

      {

        if ( | P | <= n0) adhoc(P);   //解决小规模的问题

        divide P into smaller subinstancesP1,P2,...,Pk;//分解问题

        for (i=1,i<=k,i++)

          yi=divide-and-conquer(Pi);  //递归的解各子问题

        return merge(y1,...,yk);  //将各子问题的解合并为原问题的解

      }

    人们从大量实践中发现,在用分治法设计算法时,最好使子问题的规模大致相同。即将一个问题分成大小相等的k个子问题的处理方法是行之有效的。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想,它几乎总是比子问题规模不等的做法要好。

    分治法的适用条件:

    分治法所能解决的问题一般具有以下几个特征:

    1. 该问题的规模缩小到一定的程度就可以容易地解决;因为问题的计算复杂性一般是随着问题规模的增加而增加,因此大部分问题满足这个特征。
    2. 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质这条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用
    3. 利用该问题分解出的子问题的解可以合并为该问题的解;能否利用分治法完全取决于问题是否具有这条特征,如果具备了前两条特征,而不具备第三条特征,则可以考虑贪心算法动态规划
    4. 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。这条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然也可用分治法,但一般用动态规划较好。

    分治法的复杂性分析:

    一个分治法将规模为n的问题分成k个规模为n/m的子问题去解。设分解阀值n0=1,且adhoc解规模为1的问题耗费1个单位时间。再设将原问题分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需用f(n)个单位时间。用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:


    递归的概念:

    直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数

    由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。

    分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。

    优点:结构清晰,可读性强,而且容易用数学归纳法来证明算法的正确性,因此它为设计算法、调试程序带来很大方便。

    缺点:递归算法的运行效率较低,无论是耗费的计算时间还是占用的存储空间都比非递归算法要多。

    解决方法:在递归算法中消除递归调用,使其转化为非递归算法。

    1. 采用一个用户定义的栈来模拟系统的递归调用工作栈。该方法通用性强,但本质上还是递归,只不过人工做了本来由编译器做的事情,优化效果不明显。
    2. 用递推来实现递归函数。
    3. 通过变换能将一些递归转化为尾递归,从而迭代求出结果。

    后两种方法在时空复杂度上均有较大改善,但其适用范围有限。

  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3078576.html
Copyright © 2011-2022 走看看