解递归式

一、代换法

1.    猜测结果

2.    用数学归纳法验证

3.    解出使解成立的常系数

☆ 错误的例子:

证明 n = O(1):

基准情况 1 = O(1)

假设 n-1 = O(1)

则 n = (n-1)+1 = O(1)

错误!因为不能对大O符号进行归纳,每一处的 O(1) 的常数是变化的。

如果对有限个 O(1) 加倍是没问题的,但进行 n 次加倍就不对了,

此时常数是依赖于 n 变化的。

☆ 例:T(n) = 4T(n/2) + n

基准情况:T(1) = Θ(1)

①    可以猜一种结果:如 T(n) = O(n3)

假设:当 k < n,存在 c > 0,使得 T(k) ≤ c·k3

则 T(n) = 4T(n/2) + n ≤ 4c·(n/2)3 + n

= cn3/2 + n

= cn3 - (cn3/2 - n)

若 T(n) ≤ cn3,则 cn3/2-n ≥ 0

∵ n ≥ 1,可取 c ≥ 2,此时不等式成立

又 T(1) = Θ(1) ≤ c·13 = c,任取 C0 > 0,当 c > C0 时不等式成立

∴ T(n) = O(n3) (非紧界)

②    可由 输入:n/2 -> n,n -> 2n,输出 ×4 猜测得

T(n) = O(n2)

1° 尝试假设:当 k < n,存在 c > 0,使得 T(k) ≤ c·k2

则 T(n) = 4T(n/2) + n ≤ 4c·(n/2)2 + n

= cn2 + n

若 T(n) ≤ cn2,则有 n ≤ 0 与 n ≥ 1 矛盾

尽管结果正确,T(n) = cn2 - (-n) = O(n2) - O(n) = O(n2),但不能完成归纳

接下来思路:改进归纳假设,上面的是同时假设了它没有低阶项。

2°  假设:当 k < n,存在 c1 > 0,c2 > 0,使得 T(k) ≤ c1k2 - c2k

则 T(n) = 4T(n/2) + n ≤ 4·[ c1(n/2)2 - c2n/2 ] + n

= c1n+ (1-2·c2)·n

= c1n- c2n - (c2-1)·n

∴ 当 c2-1 ≥ 0,即 c≥ 1 时,T(n) ≤ c1n- c2n

当 n = 1,T(1) = Θ(1) ≤ c- c2,∴ 对任意 c≥ 1,应有 c1 ≥ c2 。

综上,T(n) = O(n2) 得证。(紧界)

同样可用代换法证明 当 0 ≤ c2 ≤1 ≤ c1 时,T(n) = Ω(n2) 成立。所以 T(n) = Θ(n2)

二、递归树法

?        1.    构造递归树

2.    算出所有节点的运行时间和

3.    得出递归式的解

?        注:为更严谨,可以用递归树法得出答案后再用代换法验证。当然通常来说不必如此。

例:T(n) = T(n/4) + T(n/2) +n2

∴ T(n) ≤ ( 1 + 5/16 + 25/256 + ... + 5k/16k + ... ) · n2

< 2n2 = O(n2)

同时可知 T(n) = Ω(n2)

?三、主方法?

仅适用于形式如下的递归式:

T(n) = a·T( [n/b] ) + f(n),其中常数 a ≥ 1,b > 1,n 为非负整数,函数 f(n) 是渐近正函数。

有 a 个子问题,每个子问题的规模都是 n/b,加上非递归的代价 f(n) 。

注:f(n) 渐近正:存在 n0 > 0,当 n ≥ n0,f(n) > 0 。即 n 足够大时函数值总为正值。

三种情况(主定理):

1.    存在 ε > 0,有 f(n) = O(  ),(即 f(n) 多项式地小于 

则 T(n) = Θ(  )

2.    存在 ε > 0,k ≥ 0,有 f(n) = Θ(  ),

则 T(n) = Θ(  )

3.    存在 ε > 0,有 f(n) = Ω(  ),且存在 ε‘ > 0,使 a·f(n/b) ≤ (1-ε‘)·f(n)

则 T(n) = Θ( f(n) )

例:① T(n) = 4T(n/2) + n,易知 T(n) = Θ(n2)

② T(n) = 4T(n/2) + n2,易知 T(n)= Θ(n2·log2n)

③ T(n) = 4T(n/2) + n3,易知 T(n)= Θ(n3)

④ T(n) = 4T(n/2) + n2/log2n,这时主方法不适用。

By Black Storm

时间: 2024-07-30 10:59:12

解递归式的相关文章

递归式求解

算法设计中经常会用到递归,利用递归式的方法可以清晰地显示算法的整个过程,而对于分析算法的复杂度,解递归式就有了用处,这里的方法来自于<算法导论>. 1. 代换法 代换法只能用于解那种很容易猜的情形,它可用来确定一个递归式的"O"和"Ω"界. 举例,确定递归式 T(n) = 2*T(└n/2┘) + n 的一个"O"界 1.1 先猜测有某个界存在 由于这个递归式与合并排序的计算时间复杂度的递归式很相似,所以我们猜测其解为 T(n) =

分治策略(求解递归式的方法)

分解:将原问题划分成形式相同的子问题,规模可以不等,对半或2/3对1/3的划分. 解决:对于子问题的解决,很明显,采用的是递归求解的方式,如果子问题足够小了,就停止递归,直接求解. 合并:将子问题的解合并成原问题的解. 这里引出了一个如何求解子问题的问题,显然是采用递归调用栈的方式.因此,递归式与分治法是紧密相连的,使用递归式可以很自然地刻画分治法的运行时间.所以,如果你要问我分治与递归的关系,我会这样回答:分治依托于递归,分治是一种思想,而递归是一种手段,递归式可以刻画分治算法的时间复杂度.

五边形数和两个递归式

五边形数 五边形数是对每条边上有 \(n\) 个点构成的五边形的总点数的数列的称呼. 由上图,可以得出这个数列的递归式. \[ \begin{aligned} a_1&=1 \a_n&=a_{n-1}+(3n-2) \\end{aligned} \] 解递归式得到通项公式 \[ \begin{aligned} a_n&=\sum _{i=1}^n(3i-2)=\frac{n(3n-1)}{2} \end{aligned} \] 它也能通过三个三角形数得到. 狭义的五边形数中 \(n

递归式的三种求解方式

求解递归式对于分冶算法的重要性不言而喻 以下介绍了三种求解递归式的方法 1,代换法: 缺点:代换法主要的缺点在于,对于任何递归式,我们先得去猜其解,对于猜错了同学,如果不幸猜出的结果和正确结果相差太大,虽然可以推导,但是意义不大: 优点:代换法相较于递归树法更为严谨,相较于主定理应用范围更广,主定理只能求解类似于T(n) = aT(n/b)+n/c这种形式的递归式: 下面给出一个递归表达式T(n) = 2T(n/2)+n,求其解: 首先猜一下其解为O(nlgn);那么我们只需要证明T(n)<cn

【算法】2 由股票收益问题再看分治算法和递归式

回顾分治算法 分治算法的英文名叫做"divide and conquer",它的意思是将一块领土分解为若干块小部分,然后一块块的占领征服,让它们彼此异化.这就是英国人的军事策略,但我们今天要看的是算法. 如前所述,分治算法有3步,在上一篇中已有介绍,它们对应的英文名分别是:divide.conquer.combine. 接下来我们通过多个小算法来深化对分治算法的理解. 二分查找算法 问题描述:在已排序的数组A中查找是否存在数字n. 1)分:取得数组A中的中间数,并将其与n比较 2)治:

字符串匹配的双重递归式写法

字符串的匹配有很高效的KMP.Sunday等算法,可供使用.下面使用的匹配算法本质上是朴素的,但它的双重递归式的写法仍然值得借鉴. 完整示例代码 #include <stdio.h> #include <stdlib.h> #include <string.h> char *SubStrWithR(const char *str, const char *sub) { if (str == NULL || sub == NULL) return NULL; int fi

Windows C++ 非递归式(stack)深度优先遍历目录

1 #include <Windows.h> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #include <stack> 6 7 typedef void (__stdcall *P_WALK_DIR_CALLBACK)(const std::string &In_strFilePath); 8 9 int WalkDir(const char *In_p

Python算法教程第三章知识点:求和式、递归式、侏儒排序法和并归排序法

本文目录:一.求和式:二.递归式:三.侏儒排序法和并归排序法微信公众号:geekkr</br></br></br> 一.求和式 # 假设有一函数为f(),则在Python中经常使用的求和方法如下. sum(f(i) for i in range(m, n+1)) + sum(g(i) for i in range(m, n+1)) sum(f(i)+g(i) for i in range(m, n+1)) </br>二.递归式 # 举个栗子 def S(se

Chapter 4 递归式详解