分治
- 将大问题分解成一些规模较小的相同子问题(分而治之)
eg:排列
n
个元素解:一分为二,分为两个元素的小单位进行排序
1.将规模为
n
的划分为两个规模的问题(如果还大则继续划分)2.将这些问题递归求解
条件
对于函数f(n)
有基本部分和递归部分
- 基本部分
- 对于n的一个或多个值,
f(n)
必须是直接定义的,也就是非递归的
- 对于n的一个或多个值,
- 递归部分
- 右侧所出现的所有
f
的参数都必须比n小(如f(n)=f(n-1)...
)
- 右侧所出现的所有
例子-1:
\(f(n)= \left\{
\right.\)
f(n)=1
为非递归的,而n>0
时参数比n小,则可以分治
例子-2(Ackerman函数)
:
\(\left\{
\right.\)
反向替换法算得复杂度=
数学归纳法
eg:
当的时候,等于
假设
所以 \(\) 当n=2,3,4…时,函数爆炸
(共n
个2
)
排列问题
1
2
3
4
5
6
7
8
9
10
11
Perm(A,k,m):
if k==m :
for x in A:
print(x)
else:
i = k
while i<=m:
A[k],A[i]=A[i],A[k]
Perm(A,k+1,m)
A[k],A[i]=A[i],A[k]
i = i + 1
- 正整数的划分
eg:5的划分数
- 5
- 4+1
- 3+2
- 3+1+1
- 2+2+1
- 2+1+1+1
- 1+1+1+1+1
思想:求5的划分数,先求4的划分,用数学归纳法推测
递归公式:
-
:
- :
- ,正整数的划分由的划分和的划分组成
- ;正整数的最大加数不大于m的划分由的划分和的划分组成
所以: \(q(n,m)=\left\{ \right.\) eg2:汉诺塔
- 选择盘子的数量作为输入规模度量
- 选择盘子的移动作为算法的基本操作
- 移动次数为