算法设计与分析
文章目录
基础知识
一、调度问题和投资问题
调度问题
问题:有n项任务,每项任务加工时间已知。从0时刻开始陆续安排到一台机器上加工。每个任务的完成时间是从0时刻到任务加工截止的时间。求:总完成时间(所有任务完成时间之和)
最短的安排方案
实例
任务集 S={1,2,3,4,5},
加工时间:4=3,,4=8,=5,4=10,15=15
贪心法的解
发现第一个任务的加工时间出现了五次,依次类推最后一个是一次
问题建模:
贪心算法
设计策略:加工时间短的先做
算法:根据加工时间从小到大排序,依次加工
算法正确性:对所有输入实例都得到最优解
证明:
越往前计算的次数越多
但是贪心算法不一定都是正确的
反例:
有4件物品要装入背包,物品重量和价值如下:
标号 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
重量wi | 3 | 4 | 5 | 2 |
价值vi | 7 | 9 | 9 | 2 |
背包重量限制是6,问如何选择物品,使得不超重的情况下装入背包的物品价值达到最大?
- 单位重量价值最大
算法设计
- 问题建模
- 选择什么算法?如何描述这个方法?
- 这个方法是否对所有实例都得到最优解?如何证明?
- 如果不是,能否找到反例?
投资问题
![](https://i-blog.csdnimg.cn/blog_migrate/89b2ee8be24459a288293f77b0e82c01.png)
建模:
![](https://i-blog.csdnimg.cn/blog_migrate/a2038aeef280b3003307b916200b0426.png)
蛮力算法:
对所有满足下述条件的向量<x1,x2,…,xn>
x1+x2+…+xn = m
xi为非负整数,i = 1,2,… , n
计算相应的效益
f1(x1) + f2(x2) + … + fn(xn)
从中确认效益最大的向量
![](https://i-blog.csdnimg.cn/blog_migrate/2f0301833cdf5227fa5c14b5ea348dd8.png)
蛮力算法的效率
![](https://i-blog.csdnimg.cn/blog_migrate/a06a30de7ef6c6750d29616e8bc0fbd8.png)
估计序列的个数,一共有m个1,n -1个0
序列个数是输入规模的指数函数
C(m + n - 1,m)//m+n-1个位置选取m个位置来放
= ( m + n − 1 ) ! m ! ( n − 1 ) ! \frac{(m + n - 1)!}{m!(n - 1)!} m!(n−1)!(m+n−1)!
= Ω ( ( 1 + ε ) m + n − 1 ) \Omega((1 + \varepsilon)^{m +n -1}) Ω((1+ε)m+n−1) // ε \varepsilon ε是一个大于0的数
问题求解的关键
-
建模:对输入参数和解给出形式化或半形式化的描述
-
设计算法:
采用什么算法设计技术
正确性一一是否对所有的实例都得到正确的解
-
分析算法一一效率
二、问题计算复杂度的界定:排序问题
(一)排序算法的效率
以元素比较作为基本运算
算法 | 最坏情况下 | 平均情况下 |
---|---|---|
插入排序 | O(n2) | O(n2) |
冒泡排序 | O(n2) | O(n2) |
快速排序 | O(n2) | O(nlogn) |
堆排序 | O(nlogn) | O(nlogn) |
二分归并排序 | O(nlogn) | O(nlogn) |
插入排序
![](https://i-blog.csdnimg.cn/blog_migrate/87233f1bfb838e92df3b214190263a46.png)
插入2过程:与6比较小,6往后移;与5比较小,5往后移;直到与1比较大,放在1的后面;同理,4也是一样
插入排序算法运行实例:
![](https://i-blog.csdnimg.cn/blog_migrate/a7812c16e5e23fe7166d6a2b1470e7d5.png)
冒泡排序
![](https://i-blog.csdnimg.cn/blog_migrate/47bd02e1c0eeae8c332ddf5c4a422d85.png)
冒泡说的是巡回,这个是大的先回的位置
冒泡排序运行实例:
当巡回过程没有发生元素的交换巡回结束。
快速排序一次递归运行
![](https://i-blog.csdnimg.cn/blog_migrate/6f4c554a7df23128ce12ea0a879d57e3.png)
以首元素作为参照,从前往后数找第一个比首元素大的,从后往前数找第一个比首元素小的,找见以后进行交换,直到相邻元素发生交换,可知那两个数中间分界线后面是比首元素大的,前面是比首元素小的,此时2的位置就是首元素的位置,到了划分这一步,此后首元素作为分界线划分为两个子问题进行递归运行
二分归并排序
实例
![](https://i-blog.csdnimg.cn/blog_migrate/50b12a6b220a0c644f700e1f0a01ee74.png)
就是从中间先划分开,先分别排好序,分别选取每个划分中的首元素比较,把小的拿出来,一次只拿一个,直到全部排完
三、货郎问题和计算复杂性理论
货郎问题
问题:
有n个城市,已知任两个城市之间的距离.求一条每个城市恰好经过1次的回路,使得总长度最小。
建模与算法
-
输入:
有穷个城市的集合C = {C1,C2,…,Cn},距离d(Ci,Cj)= d(Cj,Ci)属于正整数,1<= i < j <= n
-
解:1,2.。。。n的排列k1,k2,。。。,kn使得
0—1背包问题
问题描述:有n个件物品要装入背包,第i件物品的重量wi,价值vi,i=1.2…,n.背包最多允许装入的重量为B,问如何选择装入背包的物品,使得总价值达到最大?
实例
现使n = 4,B = 6
标号 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
重量wi | 3 | 4 | 5 | 2 |
价值vi | 7 | 9 | 9 | 2 |
解
0—1向量<x1,x2,…xn>
xi = 1 ⇔ \Leftrightarrow ⇔物品 i 装入背包
m a x ∑ i = 1 n v i x i max\sum\limits_{i=1}^{n}v_ix_i maxi=1∑nvixi
∑ i = 1 n w i x i ≤ B \sum\limits_{i=1}^{n}w_ix_i\le B i=1∑nwixi≤B
x i = 0 , 1 , i = 1 , 2 , . . . , n x_i = 0,1,i = 1,2,...,n xi=0,1,i=1,2,...,n
双机调度
双机调度问题:有n项任务,任务m的加工时间为t,t,ez+,1.,n用两台相同的机器加工,从0时刻开始计时,完成时间是后停止加工机器的停机时间.问如何把这些任务分配到两台机器上,使得完成时间达到最小?
双机调度建模
0-1向量<x1, x2,…,xn>,xi = 1表示任务
i
i
i
分配到第一台机器,i=1.2…,n.
不妨设机器1的加工时间 ≤ 机器2的加工时间令T = t1+t2+…+tn, D=T/2向下取整,机器1的加工时间不超过D,且达到最大
四、算法及时间复杂度
1、问题及实例
问题
需要回答的一般性提问,通常含若干参数
问题描述
定义问题参数(集合,变量,函数,序列等)
说明每个参数的取值范围及参数间的关系
定义问题的解
说明解满足的条件(优化目标或约束条件)
问题实例
参数的一组赋值可得到问题的一个实例
算法
-
有限条指令的序列,确定了解决某个问题的一系列运算或操作
-
算法A解问题P
问题P的任何实例作为算法的输入,每一步都是确定的,可以在有限步停机,可以输出实例的正确解
基本运算和输入规模
-
算法的时间复杂度:针对基本运算,计算算法的运算次数
-
基本运算:比较,加法,乘法,置指针,交换……
-
输入规模:输入串编码的长度
-
算法基本运算次数可以当做可表示为输入规模的函数
-
给定问题和基本运算就决定了一个算法类
输入规模
- 排序:数组中元素个数 n n n
- 检索:被检索数组的元素个数n
- 整数乘法:两个整数的位数m,n
- 矩阵相乘:矩阵的行列数i,j,k
- 图的遍历:图的顶点数n,边数m
基本运算
-
排序:元素之间的比较
-
检索:被检索元素与数组元素的比较
-
整数乘法:每位数字相乘(位乘)1次 m位和n位整数相乘要做mn次位乘
-
矩阵相乘:每对元素乘1次
i × j i\times j i×j矩阵与 j × k j \times k j×k 矩阵相乘要做 i j k 次乘法 //总共有 i × k i \times k i×k 个元素,得到每个元素需要进行 j j j 次乘法
-
图的遍历:置指针
两种时间复杂度
最坏情况下的时间复杂度W(n)
算法求解输入规模为的实例所需要的最长时间
平均情况下的时间复杂度A(n)
在给定同样规模为 n 的输入实例的概率分布下,算法求解这些实例所需要的平均时间
A(n)计算公式
S是规模为 n 的实例集,实例 I ∈ S I \in S I∈S 的概率是 P I P_I PI
A ( n ) = ∑ I ∈ S P I t I A(n) = \sum \limits _{I \in S}P_It_I A(n)=I∈S∑PItI
在某些情况下可以假定每个输入实例概率都相等
顺序检索算法
j = 1,将x与
L
[
j
]
L[j]
L[j] 比较. 如果x =L[j],则算法停止,输出
j
j
j;如果不等,则把
j
j
j 加1,继续x与
L
[
j
]
L[j]
L[j]的比较,如果
j
j
j>n,则停机并输出0.
实例
1 | 2 | 3 | 4 | 5 |
---|
X=4,需要比较4次
x=2.5,需要比较5次
-
最坏情况估计:
不同的输入有2n+1个,分别对应:
x = L [ 1 ] , x = L [ 2 ] , . . . , x = L [ n ] x = L[1], x = L[2],...,x = L[n] x=L[1],x=L[2],...,x=L[n]x < L [ i ] , L [ 1 ] < x < L [ 2 ] , . . . , L [ n ] < x x < L[i],L[1] < x < L[2],...,L[n] < x x<L[i],L[1]<x<L[2],...,L[n]<x
最坏情况下时间:W(n)=n
最坏的输入: x x x不在L中或 x = L [ n ] x = L[n] x=L[n]
要做n次比较 -
平均情况的时间估计
x x x在L中概率为P并且每个位置出现的概率相等
A ( n ) = ∑ i = 1 n i p n + ( 1 − p ) n A(n) = \sum\limits_{i =1 }^n i\frac {p}{n}+(1-p)n A(n)=i=1∑ninp+(1−p)n
= p ( n + 1 ) 2 + ( 1 − p ) n =\frac{p(n+1)}{2}+(1-p)n =2p(n+1)+(1−p)n
改进顺序检索算法
如果元素不在数组里面,比较到它比前一个元素大,比后一个元素小就直接停机
时间估计
- 最坏情况: W ( n ) = n W(n) = n W(n)=n
五、算法的伪码表示
赋值语句:←
分支语句:if…then…
[
e
l
s
e
.
.
.
]
[else...]
[else...]
循环语句:while,for,repeat until
转向语句:goto
输出语句:return
调用:直接写过程的名字
注释:
/
/
.
.
.
//...
//...
eg:
求最大公约数(欧几里得算法)
输入:非负数m,n,m与n不全为0
输出:m与n的最大公约数
w h i l e m > 0 d o r ← n m o d m n ← m m ← r r e t u r n n while\ m > 0\ do\\r\ \gets n\ mod\ m \\n \gets m \\m \gets r\\ return\ n while m>0 dor ←n mod mn←mm←rreturn n
eg:
算法 I n s e r t S o r t ( A , n ) Insert Sort(A,n) InsertSort(A,n)
输入:n个数的数组 A A A
输出:递增序列的数组A
f o r j ← 2 t o n d o x ← A [ j ] i ← j − 1 w h i l e i > 0 a n d x < A [ i ] d o A [ i + 1 ] ← A [ i ] i ← i − 1 A [ i + 1 ] ← x for\ j \gets 2\ to\ n\ do\\x \gets A[j]\\i \gets j-1\\while\ i>0\ and\ x<A[i]\ do\\A[i+1] \gets A[i]\\i \gets i-1\\A[i+1] \gets x for j←2 to n dox←A[j]i←j−1while i>0 and x<A[i] doA[i+1]←A[i]i←i−1A[i+1]←x
第三行到最后是把 A [ j ] A[j] A[j]插入到 A [ 1.. j − 1 ] A[1..j-1] A[1..j−1]
伪码不是程序代码,只是给出关键步骤,伪码是允许过程调用的
六、函数的渐进的界
1、大 O O O符号
定义:设
f
f
f 和
g
g
g 是定义域为自然数集N上的函数。若存在正数
c
c
c和
n
0
n_0
n0,使得对一切
n
≥
n
0
n \ge n_0
n≥n0有
0
≤
f
(
n
)
≤
c
g
(
n
)
0 \le f(n) \le c\ g(n)
0≤f(n)≤c g(n)成立,则称
f
(
n
)
f(n)
f(n)的渐近的上界是
g
(
n
)
g(n)
g(n),记作
f
(
n
)
=
O
(
g
(
n
)
)
f(n) = O(g(n))
f(n)=O(g(n))
eg:
设 f ( n ) = n 2 + n , 则 f ( n ) = O ( n 2 ) , 取 c = 2 , n 0 = 1 即可 f ( n ) = O ( n 3 ) , 取 c = 1 , n 0 = 2 即可 设f(n)=n^2 +n,则\\f(n)=O(n^2),取c =2,n_0=1即可\\f(n)=O(n^3),取c = 1,n_0 =2即可 设f(n)=n2+n,则f(n)=O(n2),取c=2,n0=1即可f(n)=O(n3),取c=1,n0=2即可
注意事项
- f ( n ) = O ( g ( n ) ) , f ( n ) 的阶不高于 g ( n ) 的阶 f(n) = O(g(n)),f(n)的阶不高于g(n)的阶 f(n)=O(g(n)),f(n)的阶不高于g(n)的阶
- 可能存在多个正数c,只要指出一个即可。
- 对前面有限个值可以不满足不等式
- 常函数可以写作0(1).
2、大 Ω \Omega Ω符号
定义:设
f
f
f 和
g
g
g 是定义域为自然数集N上的函数。若存在正数
c
c
c 和
n
0
n_0
n0,使得对一切
n
≥
n
0
n \ge n_0
n≥n0有
0
≤
c
g
(
n
)
≤
f
(
n
)
0 \le c\ g(n) \le f(n)
0≤c g(n)≤f(n) 成立,则称
f
(
n
)
f(n)
f(n)的渐近的下界是
g
(
n
)
g(n)
g(n),记作
f
(
n
)
=
Ω
(
g
(
n
)
)
f(n) = \Omega(g(n))
f(n)=Ω(g(n))
注意事项
- f ( n ) = Ω ( g ( n ) ) , f ( n ) 的阶不低于 g ( n ) 的阶 f(n) = \Omega(g(n)),f(n)的阶不低于g(n)的阶 f(n)=Ω(g(n)),f(n)的阶不低于g(n)的阶
- 可能存在多个正数c,只要指出一个即可。
- 对前面有限个值可以不满足不等式
3、小 o o o符号
定义:设
f
f
f 和
g
g
g 是定义域为自然数集N上的函数。若对于任意正数
c
c
c 都存在
n
0
n_0
n0,使得对一切
n
≥
n
0
n \ge n_0
n≥n0有
0
≤
f
(
n
)
<
c
g
(
n
)
0\le f(n) < c\ g(n)
0≤f(n)<c g(n) 成立,记作
f
(
n
)
=
o
(
g
(
n
)
)
f(n) = o(g(n))
f(n)=o(g(n))
注意
-
最后面是<
-
f ( n ) = o ( g ( n ) ) , f ( n ) f(n) = o(g(n)),f(n) f(n)=o(g(n)),f(n)的阶低于 g ( n ) g(n) g(n)的阶
-
对不同正数 c , n 0 c,n_0 c,n0不一样.$\ c\ 越小 越小 越小\ n_0\ $越大
-
对前面有限个值$\ n\ $可以不满足不等式
4、小 ω \omega ω 符号
定义:设
f
f
f 和
g
g
g 是定义域为自然数集N上的函数。若对于任意正数
c
c
c 都存在
n
0
n_0
n0,使得对一切
n
≥
n
0
n \ge n_0
n≥n0有
0
≤
c
g
(
n
)
<
f
(
n
)
0\le c\ g(n) <f(n)
0≤c g(n)<f(n) 成立,记作
f
(
n
)
=
ω
(
g
(
n
)
)
f(n) = \omega(g(n))
f(n)=ω(g(n))
注意
- f ( n ) = ω ( g ( n ) ) f(n)=\omega(g(n)) f(n)=ω(g(n)) , $\ f(n)\ 的阶高于 的阶高于 的阶高于\ g(n)\ $的阶
- 对不同的正数$\ c,n_0\ 不等 , 不等, 不等,\ c \ 越大 越大 越大\ n_0 \ $越大
- 对前面有限个n值可以不满足不等式
5、 Θ \Theta Θ符号
定义:
若 f ( n ) = O ( g ( n ) ) 且 f ( n ) = Ω ( g ( n ) ) , 记作 f ( n ) = Θ ( g ( n ) ) 若f(n)=O(g(n))且f(n)=\Omega(g(n)),\\记作f(n)=\Theta(g(n)) 若f(n)=O(g(n))且f(n)=Ω(g(n)),记作f(n)=Θ(g(n))
eg:
f ( n ) = n 2 + n , g ( n ) = 100 n 2 f ( n ) = Θ ( g ( n ) ) f(n)=n^2+n,g(n)=100n^2\\f(n)=\Theta(g(n)) f(n)=n2+n,g(n)=100n2f(n)=Θ(g(n))
等阶
七、函数渐进界定理
-
定理一:
f , g f,g f,g为定义域是自然数集合的函数
-
lim n → ∞ f ( n ) g ( n ) = c > 0 ⇒ f ( n ) = Θ ( g ( n ) ) \lim\limits_{n \to \infty}\frac{f(n)}{g(n)}=c>0 \Rightarrow f(n)=\Theta(g(n)) n→∞limg(n)f(n)=c>0⇒f(n)=Θ(g(n))
-
lim n → ∞ f ( n ) g ( n ) = 0 ⇒ f ( n ) = o ( g ( n ) ) \lim\limits_{n \to \infty}\frac{f(n)}{g(n)}=0 \Rightarrow f(n)=o(g(n)) n→∞limg(n)f(n)=0⇒f(n)=o(g(n))
-
lim n → ∞ f ( n ) g ( n ) = + ∞ ⇒ f ( n ) = ω ( g ( n ) ) \lim\limits_{n \to \infty}\frac{f(n)}{g(n)}=+\infty \Rightarrow f(n)=\omega(g(n)) n→∞limg(n)f(n)=+∞⇒f(n)=ω(g(n))
-
可证明:多项式函数的阶低于指数函数的阶
n d = o ( r n ) , r > 1 , d > 0 n^d=o(r^n),r>1,d>0 nd=o(rn),r>1,d>0
-
对数函数的阶低于幂函数的阶
ln n = o ( n d ) , d > 0 \ln n=o(n^d),d>0 lnn=o(nd),d>0
-
-
-
定理二:
设 f , g , h f,g,h f,g,h为定义域是自然数集合的函数。函数的阶具有传递性
f = O ( g ) & & g = O ( h ) ⇒ f = O ( h ) f=O(g)\ \&\&\ g=O(h) \Rightarrow f=O(h) f=O(g) && g=O(h)⇒f=O(h), Ω , Θ \Omega,\Theta Ω,Θ同样是这样
-
定理三:
f , g f,g f,g为定义域是自然数集合的函数,若 f = O ( h ) 和 g = O ( h ) ⇒ f + g = O ( h ) f=O(h)和g=O(h) \Rightarrow f+g=O(h) f=O(h)和g=O(h)⇒f+g=O(h)
可以推广到有限个函数,算法是有限步骤,如果每一步上界都是 h ( n ) h(n) h(n),那么该算法就是 O ( h ( n ) ) O(h(n)) O(h(n))
在常数步的情况下取得最高阶的函数即可
八、几类重要的函数
1、基本函数类
至少指数级: 2 n , 3 n , n ! , . . . 2^n,3^n,n!,... 2n,3n,n!,...
多项式级: n , n 2 , n log n , n 1 / 2 , . . . n,n^2,n\log n,n^{1/2},... n,n2,nlogn,n1/2,...
对数多项式级: log n , ( log n ) 2 , log log n \log n,(\log n)^2,\log\log n logn,(logn)2,loglogn
2、对数函数
符号代表:
log n = l o g 2 n log k n = ( log n ) k log log n = log ( log n ) \log n=log_2n\\\log^kn=(\log n)^k\\\log \log n=\log (\log n) logn=log2nlogkn=(logn)kloglogn=log(logn)
性质:
- log 2 n = Θ ( log l n ) \log_2n=\Theta(\log_ln) log2n=Θ(logln) // l l l是其他任意的数,不关注它的底
- log b n = o ( n α ) α > 0 \log_bn=o({n^\alpha})\ \ \alpha>0 logbn=o(nα) α>0
- a log b n = n log b a a^{\log _bn}=n^{\log _ba} alogbn=nlogba
证明:
{ log b n = Θ ( ln n ) ln n = o ( n α ) ⇒ log b n = o ( n α ) α > 0 \left\{ \begin{array}{l} \log _bn\ =\varTheta \left( \ln n \right)\\ \ln n=o\left( n^{\alpha} \right)\\ \end{array} \right. \Rightarrow \log _bn=o\left( n^{\alpha} \right) \ \alpha >0 {logbn =Θ(lnn)lnn=o(nα)⇒logbn=o(nα) α>0
a log b n = n log b a a^{\log _bn}=n^{\log _ba} alogbn=nlogba
⇕ \Updownarrow ⇕
log b n log b a = log b a log b n \log _bn\log _ba=\log _ba\log _bn logbnlogba=logbalogbn
3、指数函数与阶乘
斯特灵公式(Stirling公式)
n
!
=
2
π
n
(
n
e
)
n
(
1
+
Θ
(
1
n
)
)
n!=\sqrt{2\pi n}\left( \frac{n}{e} \right) ^n\left( 1+\varTheta \left( \frac{1}{n} \right) \right)
n!=2πn(en)n(1+Θ(n1))
由公式可得,主要是由前面的那部分决定 n ! n! n!
n
!
n!
n! 的性质
n
!
=
o
(
n
n
)
n!=o\left( n^n \right)
n!=o(nn)
n ! = ω ( 2 n ) n!=\omega \left( 2^n \right) n!=ω(2n)
log ( n ! ) = Θ ( n log n ) \log \left( n! \right) =\varTheta \left( n\log n \right) log(n!)=Θ(nlogn)
eg:(利用斯特灵公式)
m元钱、投资n个项目的分配方案数
∁
m
+
n
−
1
m
=
(
m
+
n
−
1
)
!
m
!
(
n
−
1
)
!
\complement _{m+n-1}^{m}=\frac{\left( m+n-1 \right) !}{m!\left( n-1 \right) !}
∁m+n−1m=m!(n−1)!(m+n−1)!
= 2 π ( m + n − 1 ) ( m + n − 1 ) m + n − 1 ( 1 + Θ ( 1 m + n − 1 ) ) 2 π m m m ( 1 + Θ ( 1 m ) ) 2 π ( n − 1 ) ( n − 1 ) n − 1 ( 1 + Θ ( 1 n − 1 ) ) =\frac{\sqrt{2\pi \left( m+n-1 \right)}\left( m+n-1 \right) ^{m+n-1}\left( 1+\varTheta \left( \frac{1}{m+n-1} \right) \right)}{\sqrt{2\pi m}m^m\left( 1+\varTheta \left( \frac{1}{m} \right) \right) \sqrt{2\pi \left( n-1 \right)}\left( n-1 \right) ^{n-1}\left( 1+\varTheta \left( \frac{1}{n-1} \right) \right)} =2πmmm(1+Θ(m1))2π(n−1)(n−1)n−1(1+Θ(n−11))2π(m+n−1)(m+n−1)m+n−1(1+Θ(m+n−11))
= Θ ( ( 1 + ε ) m + n − 1 ) =\varTheta \left( \left( 1+\varepsilon \right) ^{m+n-1} \right) =Θ((1+ε)m+n−1)
log
(
n
!
)
=
Ω
(
n
log
n
)
\log(n!)=\Omega(n\log n)
log(n!)=Ω(nlogn) 的证明
log
(
n
!
)
=
∑
k
=
1
n
log
k
≥
∫
1
n
log
x
d
x
\log \left( n! \right) =\sum_{k=1}^n{\log k\ge \int_1^n{\log xdx}}
log(n!)=k=1∑nlogk≥∫1nlogxdx
=
log
e
(
n
ln
n
−
n
+
1
)
=
Ω
(
n
log
n
)
=\log e\left( n\ln n-n+1 \right) =\varOmega \left( n\log n \right)
=loge(nlnn−n+1)=Ω(nlogn)
log ( n ! ) = O ( n log n ) \log(n!)=O(n\log n) log(n!)=O(nlogn)的证明
log ( n ! ) = ∑ k = 1 n log k ≤ ∫ 2 n + 1 log x d x = O ( n log n ) \log \left( n! \right) \ =\sum_{k\ =1}^n{\log\text{\ }k}\ \le \int_2^{n+1}{\log\text{\ }xdx=O\left( n\log n \right)} log(n!) =k =1∑nlog k ≤∫2n+1log xdx=O(nlogn)
2~3之间的一长条矩形的面积等于 l o g 2 log2 log2,依次类推
4、取整函数
定义不多赘述
应用:二分检索输入数组长度:n中位数的位置:
⌊
n
2
⌋
\lfloor \frac{n}{2} \rfloor
⌊2n⌋与中位数比较后子问题大小
⌊
n
2
⌋
\lfloor \frac{n}{2} \rfloor
⌊2n⌋
性质:
x
−
1
<
⌊
x
⌋
≤
⌈
x
⌉
<
x
+
1
x-1<\lfloor x \rfloor \le \lceil x \rceil <x+1
x−1<⌊x⌋≤⌈x⌉<x+1
⌊ x + n ⌋ = ⌊ x ⌋ + n , ⌈ x + n ⌉ = ⌈ x ⌉ + n , n 为整数 \lfloor x+n \rfloor =\lfloor x \rfloor +n,\lceil x+n \rceil =\lceil x \rceil +n,n\text{为整数} ⌊x+n⌋=⌊x⌋+n,⌈x+n⌉=⌈x⌉+n,n为整数
⌈ n 2 ⌉ + ⌊ n 2 ⌋ = n \lceil \frac{n}{2} \rceil +\lfloor \frac{n}{2} \rfloor =n ⌈2n⌉+⌊2n⌋=n
⌈ ⌈ n a ⌉ b ⌉ = ⌈ n a b ⌉ , ⌊ ⌊ n a ⌋ b ⌋ = ⌊ n a b ⌋ \lceil \frac{\lceil \frac{n}{a} \rceil}{b} \rceil =\lceil \frac{n}{ab} \rceil ,\lfloor \frac{\lfloor \frac{n}{a} \rfloor}{b} \rfloor =\lfloor \frac{n}{ab} \rfloor ⌈b⌈an⌉⌉=⌈abn⌉,⌊b⌊an⌋⌋=⌊abn⌋
按照阶排序
2
2
n
,
n
!
,
n
2
n
,
(
3
2
)
n
,
(
log
n
)
log
n
=
n
log
log
n
,
2^{2^n},n!,n2^n,\left( \dfrac{3}{2} \right) ^n,\left( \log n \right) ^{\log n}=n^{\log\log n},
22n,n!,n2n,(23)n,(logn)logn=nloglogn,
n 3 , log ( n ! ) = Θ ( n log n ) , n = 2 log n , n^3,\log \left( n! \right) =\varTheta \left( n\log n \right) ,n=2^{\log n}, n3,log(n!)=Θ(nlogn),n=2logn,
log 2 n , log n , log n , log log n , \log ^2n,\log n,\sqrt{\log n},\log\log n, log2n,logn,logn,loglogn,
n 1 log n = 1 n^{\dfrac{1}{\log n}}=1 nlogn1=1
九、求和
1、序列求和的方法
等差:
∑
k
=
1
n
a
k
=
n
(
a
1
+
a
n
)
2
\sum_{k=1}^n{a_k}=\frac{n\left( a_1+a_n \right)}{2}
k=1∑nak=2n(a1+an)
等比:
∑
k
=
0
n
a
q
k
=
a
(
1
−
q
n
+
1
)
1
−
q
\sum_{k=0}^n{aq^k}=\frac{a\left( 1-q^{n+1} \right)}{1-q}
k=0∑naqk=1−qa(1−qn+1)
∑ k = 0 ∞ a q k = a 1 − q ( q < 1 ) \sum_{k=0}^{\infty}{aq^k}=\frac{a}{1-q}\left( q<1 \right) k=0∑∞aqk=1−qa(q<1)
调和级数:
∑
k
=
1
n
1
k
=
ln
n
+
O
(
1
)
\sum_{k=1}^n{\frac{1}{k}}=\ln n+O\left( 1 \right)
k=1∑nk1=lnn+O(1)
eg:
∑
t
=
1
k
t
2
t
−
1
=
∑
t
=
1
k
t
(
2
t
−
2
t
−
1
)
/
/
拆项
\sum_{t=1}^k{t2^{t-1}}=\sum_{t=1}^k{t\left( 2^t-2^{t-1} \right)}//拆项
t=1∑kt2t−1=t=1∑kt(2t−2t−1)//拆项
= ∑ t = 1 k t 2 t − ∑ t = 1 k t 2 t − 1 = ∑ t = 1 k t 2 t − ∑ t = 0 k − 1 ( t + 1 ) 2 t / / 变限 =\sum_{t=1}^k{t2^t}-\sum_{t=1}^k{t2^{t-1}}=\sum_{t=1}^k{t2^t}-\sum_{t=0}^{k-1}{\left( t+1 \right) 2^t}//变限 =t=1∑kt2t−t=1∑kt2t−1=t=1∑kt2t−t=0∑k−1(t+1)2t//变限
∑ t = 1 k t 2 t − ∑ t = 0 k − 1 t 2 t − ∑ t = 0 k − 1 2 t / / 拆项 \sum_{t=1}^k{t2^t}-\sum_{t=0}^{k-1}{t2^t}-\sum_{t=0}^{k-1}{2^t}//拆项 t=1∑kt2t−t=0∑k−1t2t−t=0∑k−12t//拆项
= k 2 k − ( 2 k − 1 ) = ( k − 1 ) 2 k + 1 =k2^k-\left( 2^k-1 \right) =\left( k-1 \right) 2^k+1 =k2k−(2k−1)=(k−1)2k+1
二分检索算法
算法 B i n a r y S e a r c h ( T , l , r , x ) BinarySearch(T,l,r,x) BinarySearch(T,l,r,x)
输入:数组 T ,下标从 l l l到 r r r;数 x x x
输出:
j
j
j
l
←
1
;
r
←
n
l\gets 1;r\gets n
l←1;r←n
w h i l e l ≤ r d o while\ l\le r\ do while l≤r do
m ← ⌊ ( l + r ) 2 ⌋ m\gets \lfloor \dfrac{\left( l+r \right)}{2} \rfloor m←⌊2(l+r)⌋
i f T [ m ] = x t h e n r e t u r n m / / x 中位元素 if\ T\left[ m \right] \ =\ x\ then\ return\ m\ //x\text{中位元素} if T[m] = x then return m //x中位元素
e l s e i f T [ m ] > x t h e n r ← m − 1 else\ if\ T\left[ m \right] \ >\ x\ then\ r\gets m-1 else if T[m] > x then r←m−1
e l s e l ← m + 1 else\ l\gets m+1 else l←m+1
r e t u r n 0 return\ 0 return 0
输入有$2n+1\ $中输入
比较$\ t\ $次的输入个数
x |
---|
比较1次:一个
x | x |
---|
比较2次:2个
x | x | x | x |
---|
比较3次:4个
对 t = 1 , 2 , . . . , k − 1 t=1,2,...,k-1 t=1,2,...,k−1,比较$\ t \ $次: 2 t − 1 2^{t-1} 2t−1个
比较$\ k \ $次的输入有 2 k − 1 + n + 1 2^{k-1}+n+1 2k−1+n+1个
总次数:每个输入乘以次数再求和
二分检索平均时间复杂度
假设
n
=
2
k
−
1
n=2^k-1
n=2k−1,各种输入概率相等
A
(
n
)
=
1
2
n
+
1
[
∑
t
=
1
k
−
1
t
2
t
−
1
+
k
(
2
k
−
1
+
n
+
1
)
]
A\left( n \right) =\frac{1}{2n+1}\left[ \sum_{t=1}^{k-1}{t2^{t-1}}+k\left( 2^{k-1}+n+1 \right) \right]
A(n)=2n+11[t=1∑k−1t2t−1+k(2k−1+n+1)]
= 1 2 n + 1 [ ∑ t = 1 k t 2 t − 1 + k ( n + 1 ) ] =\frac{1}{2n+1}\left[ \sum_{t=1}^k{t2^{t-1}}+k\left( n+1 \right) \right] =2n+11[t=1∑kt2t−1+k(n+1)]
= 1 2 n + 1 [ ( k − 1 ) 2 k + 1 + k ( n + 1 ) ] =\frac{1}{2n+1}\left[ \left( k-1 \right) 2^k+1+k\left( n+1 \right) \right] =2n+11[(k−1)2k+1+k(n+1)]
= k 2 k − 2 k + 1 + k 2 k 2 k + 1 − 1 ≈ k − 1 2 = ⌊ log n ⌋ + 1 2 =\frac{k2^k-2^k+1+k2^k}{2^{k+1}-1}\thickapprox k-\frac{1}{2}=\lfloor \log n \rfloor +\frac{1}{2} =2k+1−1k2k−2k+1+k2k≈k−21=⌊logn⌋+21
估计合式上界的放大法
1、放大法:
∑
k
=
1
n
a
k
≤
n
a
max
\sum_{k=1}^n{a_k}\le na_{\max}
k=1∑nak≤namax
这个比较粗糙
2、存在 r < 1 \ r\ <1 r <1,对一切 k ≥ 0 有 a k + 1 a k ≤ r k\ge 0\text{有}\dfrac{a_{k+1}}{a_k}\le r k≥0有akak+1≤r成立