无论在以后找工作还是面试中,都离不开算法设计与分析。本博文总结了相关算法设计的题目,旨在帮助加深对贪心算法、动态规划、回溯等算法的理解。
1、计算下述算法执行的加法次数:
输入:n=2^t //t为整数
输出:加法次数 k
K=0
while n>=1 do
for j=1 to n do
k:= k+1
n= n/2
return k
解析:第一次循环执行n次加法,第二次循环执行1/2次加法,第三次循环执行1/ 2 2 = 1 / 4 2^2=1/4 22=1/4次加法…因此,上述算法执行加法的次数为 n + 1 2 n + 1 4 n + . . . + 1 n+\frac{1}{2}n+\frac{1}{4}n+...+1 n+21n+41n+...+1= n + n − 1 2 n + 1 2 n − 1 4 n + . . . . − 1 n+n-\frac{1}{2}n+\frac{1}{2}n-\frac{1}{4}n+....-1 n+n−21n+21n−41n+....−1=2n-1
2、考虑下面每对函数 f(n) 和 g(n) ,如果它们的阶相等则使用Θ记号,否则使用 O 记号表示它们的关系
f ( n ) = ( n 2 − n ) / 2 , g ( n ) = 6 n f(n)=(n^2-n)/2,g(n)=6n f(n)=(n2−n)/2,g(n)=6n
解析:
前导知识:
1 < l o g n < n < n l o g n < n 2 < n 3 < 2 n < n ! < n n 1
g ( n ) = O ( f ( n ) ) g(n)=O(f(n)) g(n)=O(f(n)),因为 f ( n ) = Θ ( n 2 ) , g ( n ) = Θ ( n ) f(n)=\Theta(n^2),g(n)=\Theta(n) f(n)=Θ(n2),g(n)=Θ(n)
f ( n ) = n + 2 n , g ( n ) = n 2 f(n)=n+2\sqrt{n},g(n)=n^2 f(n)=n+2n,g(n)=n2
解析: f ( n ) = O ( g ( n ) ) f(n)=O(g(n)) f(n)=O(g(n)),因为 f ( n ) = Θ ( n ) , g ( n ) = Θ ( n 2 ) f(n)=\Theta(n),g(n)=\Theta(n^2) f(n)=Θ(n),g(n)=Θ(n2)
f ( n ) = n + n l o g n , g ( n ) = n n f(n)=n+nlogn,g(n)=n\sqrt{n} f(n)=n+nlogn,g(n)=nn
解析: f ( n ) = O ( g ( n ) ) f(n)=O(g(n)) f(n)=O(g(n)),因为 f ( n ) = Θ ( n l o g n ) , g ( n ) = Θ ( n 3 2 ) f(n)=\Theta(nlogn),g(n)=\Theta(n^\frac{3}{2}) f(n)=Θ(nlogn),g(n)=Θ(n23)
f ( n ) = 2 ( l o g n ) 2 , g ( n ) = l o g n + 1 f(n)=2(log^n)^2,g(n)=logn+1 f(n)=2(logn)2,g(n)=logn+1
解析: g ( n ) = O ( f ( n ) ) g(n)=O(f(n)) g(n)=O(f(n))
f ( n ) = l o g ( n ! ) , g ( n ) = n 1.05 f(n)=log(n!),g(n)=n^{1.05} f(n)=log(n!),g(n)=n1.05
解析: f ( n ) = O ( g ( n ) ) f(n)=O(g(n)) f(n)=O(g(n))
3、在表1.1中填入 true 或 false
解析:利用上题的前导知识就可以得出。
4、对于下面每个函数 f(n),用f(n) =Θ(g(n))的形式,其中g(n)要尽可能简洁,然后按阶递增序排列它们(最后一列)
( n − 2 ) ! = Θ ( ( n − 2 ) ! ) (n-2)!=\Theta((n-2)!) (n−2)!=Θ((n−2)!)
5 l o g ( n + 100 ) 10 = Θ ( l o g n ) 5log(n+100)^{10}=\Theta(logn) 5log(n+100)10=Θ(logn)
2 2 n = Θ ( 4 n ) 2^{2n}=\Theta(4^n) 22n=Θ(4n)
0.001 n 4 + 3 n 3 + 1 = Θ ( n 4 ) 0.001n^4+3n^3+1=\Theta(n^4) 0.001n4+3n3+1=Θ(n4)
( l n n ) 2 = Θ ( l n 2 n ) (ln n)^2=\Theta(ln^2n) (lnn)2=Θ(ln2n)
n 3 + l o g n = Θ ( n 3 ) \sqrt[3]n+logn=\Theta(\sqrt[3]n) 3n+logn=Θ(3n)
3 n = Θ ( 3 n ) 3^n=\Theta(3^n) 3n=Θ(3n)
l o g ( n ! ) = Θ ( n l o g n ) log(n!)=\Theta(nlogn) log(n!)=Θ(nlogn)
l o g ( n n + 1 ) = Θ ( n l o g n ) log(n^{n+1})=\Theta(nlogn) log(nn+1)=Θ(nlogn)
1 + 1 2 + . . . . + 1 n = Θ ( l o g n ) 1+\frac{1}{2}+....+\frac{1}{n}=\Theta(logn) 1+21+....+n1=Θ(logn)
解析:最后一个用到了调和公式: ∑ k = 1 n 1 k = l o g n + O ( 1 ) \sum_{k=1}^{n}\frac{1}{k}=logn+O(1) ∑k=1nk1=logn+O(1)
按阶递增的顺序排列:
1 + 1 2 + . . . . + 1 n 1+\frac{1}{2}+....+\frac{1}{n} 1+21+....+n1、 5 l o g ( n + 100 ) 10 5log(n+100)^{10} 5log(n+100)10、 ( l n n ) 2 (ln n)^2 (lnn)2、 n 3 + l o g n \sqrt[3]n+logn 3n+logn、 l o g ( n ! ) log(n!) log(n!)、 l o g ( n n + 1 ) log(n^{n+1}) log(nn+1)、 0.001 n 4 + 3 n 3 + 1 0.001n^4+3n^3+1 0.001n4+3n3+1、 3 n 3^n 3n、 2 2 n 2^{2n} 22n、 ( n − 2 ) ! (n-2)! (n−2)!
5、求解递推方程
前导知识:主定理
前导知识:递归树:
例子:递归树是一棵节点带权的二叉树,初始递归树只有一个结点,标记为权重W(n),然后不断进行迭代,最后直到树种不再含有权为函数的结点为止,然后将树根结点到树叶节点的全部权值加起来,即为算法的复杂度。以二路归并排序算法的递推方程为例子进行递归树讲解。
已知 W ( n ) = 2 W ( n / 2 ) + n − 1 W(n)=2W(n/2)+n−1 W(n)=2W(n/2)+n−1,并且W(1)=0,递归树求解过程如下图:
(1) T ( n ) = T ( n − 1 ) + n 2 , T ( 1 ) = 1 T(n)=T(n-1)+n^2,T(1)=1 T(n)=T(n−1)+n2,T(1)=1
解析:
T ( n − 1 ) = T ( n − 2 ) + ( n − 1 ) 2 T(n-1)=T(n-2)+(n-1)^2 T(n−1)=T(n−2)+(n−1)2
T ( n − 2 ) = T ( n − 3 ) + ( n − 2 ) 2 T(n-2)=T(n-3)+(n-2)^2 T(n−2)=T(n−3)+(n−2)2
T ( n − 3 ) = T ( n − 4 ) + ( n − 3 ) 2 T(n-3)=T(n-4)+(n-3)^2 T(n−3)=T(n−4)+(n−3)2
…
因此,将上述各式相加,得到 T ( n ) = 1 + 2 2 + 3 3 + . . . + n 2 = n ( n + 1 ) ( 2 n + 1 ) 6 T(n)=1+2^2+3^3+...+n^2=\frac{n(n+1)(2n+1)}{6} T(n)=1+22+33+...+n2=6n(n+1)(2n+1)
(2) T ( n ) = 9 T ( n / 3 ) + n , T ( 1 ) = 1 T(n)=9T(n/3)+n,T(1)= 1 T(n)=9T(n/3)+n,T(1)=1
解析: a = 9 , b = 3 a=9,b=3 a=9,b=3,因此, n l o g b a = n l o g 3 9 = n 2 , f ( n ) = n n^{log_b^a}=n^{log_3^9}=n^2,f(n)=n nlogba=nlog39=n2,f(n)=n
因为, f ( n ) < O ( n 2 ) f(n)
(3) T ( n ) = T ( n / 2 ) + T ( n / 4 ) + c n , T ( 1 ) = 1 T(n)=T(n/2) + T(n/4) +cn,T(1)=1 T(n)=T(n/2)+T(n/4)+cn,T(1)=1
解析:
(3) T ( n ) = 5 T ( n / 2 ) + ( n l o g n ) 2 , T ( 1 ) = 1 T(n)=5T(n/2) + (nlogn)^2,T(1)=1 T(n)=5T(n/2)+(nlogn)2,T(1)=1
解析: a = 5 , b = 2 , n l o g b a = n l o g 2 5 , f ( n ) = ( n l o g n ) 2 a=5,b=2,n^{log_b^a}=n^{log_2^5},f(n)=(nlogn)^2 a=5,b=2,nlogba=nlog25,f(n)=(nlogn)2,由于, n l o g 2 5 > O ( f ( n ) ) n^{log_2^5}>O(f(n)) nlog25>O(f(n)),因此,T(n)= O ( n l o g 2 5 ) O(n^{log_2^5}) O(nlog25)
5、设A是 n 个非0实数构成的数组,设计一算法重排数组的数,使得负数都在正数的前面。
要求时间、空间复杂性为 O(n)和O(1)
解析:由于时间复杂度为O(n),空间复杂度为O(1),说明只需要遍历一次数组,不需要额外的存储空间,就能完成该问题的求解。
算法:
6、给定含 n 个不同的数的数组 L = < X 1 , … , X n L=
解析:用二分法:
7、设A 是 n 个不同的数排好序的数组,给定数 L 和 U , L 解析:一般对于已经排好序的数组相关的算法,可以想想是否可以用到二分算法。
使用二分查找:
8、用动态规划算法求解下面的组合优化问题:
m a x { g 1 ( x 1 ) + g 2 ( x 2 ) + g 3 ( x 3 ) } max\{g_1(x_1)+g_2(x_2)+g_3(x_3)\} max{g1(x1)+g2(x2)+g3(x3)}
x 1 2 + x 2 2 + x 3 2 < = 10 x_1^2+x_2^2+x_3^2 <= 10 x12+x22+x32<=10
x1, x2, x3 为非负整数
其中函数 g1(x), g2(x), g3(x) 的值给在下表中
解析:设 F k ( x ) F_k(x) Fk(x)表示目标函数的最大值
这里设置标志函数 x k ( x ) x_k(x) xk(x),表示当目标函数取到最大时,分配给第k个 g k g_k gk的参数值
因此有:
F k ( x ) = m a x { 0 < = x k < = ⌊ x ⌋ } { F k − 1 ( x − x k ) + g k ( x k ) } F_k(x)=max_{\{0<=x_k<=\left \lfloor x \right \rfloor \}}\{ F_{k-1}(x-x_k)+g_k(x_k) \} Fk(x)=max{0<=xk<=⌊x⌋}{Fk−1(x−xk)+gk(xk)}
F 1 ( x ) = g 1 ( ⌊ x ⌋ ) F_1(x)=g_1(\left \lfloor \sqrt x \right \rfloor) F1(x)=g1(⌊x⌋)
首先计算 F 1 ( x ) F_1(x) F1(x):
F 1 ( 0 ) = 2 , x 1 ( x ) = 0 F_1(0)=2,x_1(x)=0 F1(0)=2,x1(x)=0,
F 1 ( 1 ) = 4 , F 1 ( 2 ) = 4 , F 1 ( 3 ) = 4 , x 1 ( x ) = 1 F_1(1)=4,F_1(2)=4,F_1(3)=4,x_1(x)=1 F1(1)=4,F1(2)=4,F1(3)=4,x1(x)=1,
F 1 ( 4 ) = 7 , F 1 ( 5 ) = 7 , F 1 ( 6 ) = 7 , F 1 ( 8 ) = 7 , x 1 ( x ) = 2 F_1(4)=7,F_1(5)=7,F_1(6)=7,F_1(8)=7,x_1(x)=2 F1(4)=7,F1(5)=7,F1(6)=7,F1(8)=7,x1(x)=2,
F 1 ( 9 ) = 11 , F 1 ( 10 ) = 11 , x 1 ( x ) = 3 F_1(9)=11,F_1(10)=11,x_1(x)=3 F1(9)=11,F1(10)=11,x1(x)=3
计算 F 2 ( x ) F_2(x) F2(x):
F 2 ( 0 ) = m a x { g 2 ( 0 ) + F 1 ( 0 ) } = 7 , x 2 ( x ) = 0 F_2(0)=max{\{ g_2(0)+F_1(0) \}}=7,x_2(x)=0 F2(0)=max{g2(0)+F1(0)}=7,x2(x)=0
F 2 ( 1 ) = m a x { g 2 ( 0 ) + F 1 ( 1 ) , g 2 ( 1 ) + F 1 ( 0 ) } = 12 , x 2 ( x ) = 1 F_2(1)=max{\{ g_2(0)+F_1(1),g_2(1)+F_1(0) \}}=12,x_2(x)=1 F2(1)=max{g2(0)+F1(1),g2(1)+F1(0)}=12,x2(x)=1
F 2 ( 2 ) = m a x { g 2 ( 0 ) + F 1 ( 2 ) , g 2 ( 1 ) + F 1 ( 1 ) } = 14 , x 2 ( x ) = 1 F_2(2)=max{\{ g_2(0)+F_1(2) ,g_2(1)+F_1(1)\}}=14,x_2(x)=1 F2(2)=max{g2(0)+F1(2),g2(1)+F1(1)}=14,x2(x)=1
F 2 ( 3 ) = m a x { g 2 ( 0 ) + F 1 ( 3 ) , g 2 ( 1 ) + F 1 ( 2 ) } = 14 , x 2 ( x ) = 1 F_2(3)=max{\{ g_2(0)+F_1(3),g_2(1)+F_1(2) \}}=14,x_2(x)=1 F2(3)=max{g2(0)+F1(3),g2(1)+F1(2)}=14,x2(x)=1
F 2 ( 4 ) = m a x { g 2 ( 0 ) + F 1 ( 4 ) , g 2 ( 1 ) + F 1 ( 3 ) , g 2 ( 2 ) + F 1 ( 0 ) } = 18 , x 2 ( x ) = 2 F_2(4)=max{\{ g_2(0)+F_1(4),g_2(1)+F_1(3),g_2(2)+F_1(0) \}}=18,x_2(x)=2 F2(4)=max{g2(0)+F1(4),g2(1)+F1(3),g2(2)+F1(0)}=18,x2(x)=2
F 2 ( 5 ) = m a x { g 2 ( 0 ) + F 1 ( 5 ) , g 2 ( 1 ) + F 1 ( 4 ) , g 2 ( 2 ) + F 1 ( 1 ) } = 20 , x 2 ( x ) = 2 F_2(5)=max{\{ g_2(0)+F_1(5),g_2(1)+F_1(4),g_2(2)+F_1(1) \}}=20,x_2(x)=2 F2(5)=max{g2(0)+F1(5),g2(1)+F1(4),g2(2)+F1(1)}=20,x2(x)=2
F 2 ( 6 ) = m a x { g 2 ( 0 ) + F 1 ( 6 ) , g 2 ( 1 ) + F 1 ( 5 ) , g 2 ( 2 ) + F 1 ( 2 ) } = 20 , x 2 ( x ) = 2 F_2(6)=max{\{ g_2(0)+F_1(6),g_2(1)+F_1(5),g_2(2)+F_1(2) \}}=20,x_2(x)=2 F2(6)=max{g2(0)+F1(6),g2(1)+F1(5),g2(2)+F1(2)}=20,x2(x)=2
F 2 ( 7 ) = m a x { g 2 ( 0 ) + F 1 ( 7 ) , g 2 ( 1 ) + F 1 ( 6 ) , g 2 ( 2 ) + F 1 ( 3 ) } = 20 , x 2 ( x ) = 2 F_2(7)=max{\{ g_2(0)+F_1(7),g_2(1)+F_1(6),g_2(2)+F_1(3) \}}=20,x_2(x)=2 F2(7)=max{g2(0)+F1(7),g2(1)+F1(6),g2(2)+F1(3)}=20,x2(x)=2
F 2 ( 8 ) = m a x { g 2 ( 0 ) + F 1 ( 8 ) , g 2 ( 1 ) + F 1 ( 7 ) , g 2 ( 2 ) + F 1 ( 4 ) } = 23 , x 2 ( x ) = 2 F_2(8)=max{\{ g_2(0)+F_1(8),g_2(1)+F_1(7),g_2(2)+F_1(4) \}}=23,x_2(x)=2 F2(8)=max{g2(0)+F1(8),g2(1)+F1(7),g2(2)+F1(4)}=23,x2(x)=2
F 2 ( 9 ) = m a x { g 2 ( 0 ) + F 1 ( 9 ) , g 2 ( 1 ) + F 1 ( 8 ) , g 2 ( 2 ) + F 1 ( 5 ) , g 2 ( 3 ) + F 1 ( 0 ) } = 23 , x 2 ( x ) = 2 F_2(9)=max{\{ g_2(0)+F_1(9),g_2(1)+F_1(8),g_2(2)+F_1(5),g_2(3)+F_1(0)\}}=23,x_2(x)=2 F2(9)=max{g2(0)+F1(9),g2(1)+F1(8),g2(2)+F1(5),g2(3)+F1(0)}=23,x2(x)=2
F 2 ( 10 ) = m a x { g 2 ( 0 ) + F 1 ( 10 ) , g 2 ( 1 ) + F 1 ( 9 ) , g 2 ( 2 ) + F 1 ( 6 ) , g 2 ( 3 ) + F 1 ( 1 ) } = 24 , x 2 ( x ) = 3 F_2(10)=max{\{ g_2(0)+F_1(10),g_2(1)+F_1(9),g_2(2)+F_1(6),g_2(3)+F_1(1)\}}=24,x_2(x)=3 F2(10)=max{g2(0)+F1(10),g2(1)+F1(9),g2(2)+F1(6),g2(3)+F1(1)}=24,x2(x)=3
计算 F 3 ( x ) F_3(x) F3(x):
F 3 ( 0 ) = m a x { g 3 ( 0 ) + F 2 ( 0 ) } = 15 , x 2 ( x ) = 0 F_3(0)=max{\{ g_3(0)+F_2(0)\}}=15,x_2(x)=0 F3(0)=max{g3(0)+F2(0)}=15,x2(x)=0
F 3 ( 1 ) = m a x { g 3 ( 0 ) + F 2 ( 1 ) , g 3 ( 1 ) + F 2 ( 0 ) } = 20 , x 2 ( x ) = 0 F_3(1)=max{\{ g_3(0)+F_2(1),g_3(1)+F_2(0)\}}=20,x_2(x)=0 F3(1)=max{g3(0)+F2(1),g3(1)+F2(0)}=20,x2(x)=0
F 3 ( 2 ) = m a x { g 3 ( 0 ) + F 2 ( 2 ) , g 3 ( 1 ) + F 2 ( 1 ) } = 24 , x 2 ( x ) = 1 F_3(2)=max{\{ g_3(0)+F_2(2),g_3(1)+F_2(1)\}}=24,x_2(x)=1 F3(2)=max{g3(0)+F2(2),g3(1)+F2(1)}=24,x2(x)=1
F 3 ( 3 ) = m a x { g 3 ( 0 ) + F 2 ( 3 ) , g 3 ( 1 ) + F 2 ( 2 ) } = 26 , x 2 ( x ) = 1 F_3(3)=max{\{ g_3(0)+F_2(3),g_3(1)+F_2(2)\}}=26,x_2(x)=1 F3(3)=max{g3(0)+F2(3),g3(1)+F2(2)}=26,x2(x)=1
F 3 ( 4 ) = m a x { g 3 ( 0 ) + F 2 ( 4 ) , g 3 ( 1 ) + F 2 ( 3 ) , g 3 ( 2 ) + F 2 ( 0 ) } = 26 , x 2 ( x ) = 1 F_3(4)=max{\{ g_3(0)+F_2(4),g_3(1)+F_2(3),g_3(2)+F_2(0)\}}=26,x_2(x)=1 F3(4)=max{g3(0)+F2(4),g3(1)+F2(3),g3(2)+F2(0)}=26,x2(x)=1
F 3 ( 5 ) = m a x { g 3 ( 0 ) + F 2 ( 5 ) , g 3 ( 1 ) + F 2 ( 4 ) , g 3 ( 2 ) + F 2 ( 1 ) } = 30 , x 2 ( x ) = 1 F_3(5)=max{\{ g_3(0)+F_2(5),g_3(1)+F_2(4),g_3(2)+F_2(1)\}}=30,x_2(x)=1 F3(5)=max{g3(0)+F2(5),g3(1)+F2(4),g3(2)+F2(1)}=30,x2(x)=1
F 3 ( 6 ) = m a x { g 3 ( 0 ) + F 2 ( 6 ) , g 3 ( 1 ) + F 2 ( 5 ) , g 3 ( 2 ) + F 2 ( 2 ) } = 32 , x 2 ( x ) = 1 F_3(6)=max{\{ g_3(0)+F_2(6),g_3(1)+F_2(5),g_3(2)+F_2(2)\}}=32,x_2(x)=1 F3(6)=max{g3(0)+F2(6),g3(1)+F2(5),g3(2)+F2(2)}=32,x2(x)=1
F 3 ( 7 ) = m a x { g 3 ( 0 ) + F 2 ( 7 ) , g 3 ( 1 ) + F 2 ( 6 ) , g 3 ( 2 ) + F 2 ( 3 ) } = 32 , x 2 ( x ) = 1 F_3(7)=max{\{ g_3(0)+F_2(7),g_3(1)+F_2(6),g_3(2)+F_2(3)\}}=32,x_2(x)=1 F3(7)=max{g3(0)+F2(7),g3(1)+F2(6),g3(2)+F2(3)}=32,x2(x)=1
F 3 ( 8 ) = m a x { g 3 ( 0 ) + F 2 ( 8 ) , g 3 ( 1 ) + F 2 ( 7 ) , g 3 ( 2 ) + F 2 ( 4 ) } = 35 , x 2 ( x ) = 2 F_3(8)=max{\{ g_3(0)+F_2(8),g_3(1)+F_2(7),g_3(2)+F_2(4)\}}=35,x_2(x)=2 F3(8)=max{g3(0)+F2(8),g3(1)+F2(7),g3(2)+F2(4)}=35,x2(x)=2
F 3 ( 9 ) = m a x { g 3 ( 0 ) + F 2 ( 9 ) , g 3 ( 1 ) + F 2 ( 8 ) , g 3 ( 2 ) + F 2 ( 5 ) , g 3 ( 3 ) + F 2 ( 0 ) } = 37 , x 2 ( x ) = 2 F_3(9)=max{\{ g_3(0)+F_2(9),g_3(1)+F_2(8),g_3(2)+F_2(5),g_3(3)+F_2(0)\}}=37,x_2(x)=2 F3(9)=max{g3(0)+F2(9),g3(1)+F2(8),g3(2)+F2(5),g3(3)+F2(0)}=37,x2(x)=2
F 3 ( 10 ) = m a x { g 3 ( 0 ) + F 2 ( 10 ) , g 3 ( 1 ) + F 2 ( 9 ) , g 3 ( 2 ) + F 2 ( 6 ) , g 3 ( 3 ) + F 2 ( 1 ) } = 37 , x 2 ( x ) = 2 F_3(10)=max{\{ g_3(0)+F_2(10),g_3(1)+F_2(9),g_3(2)+F_2(6),g_3(3)+F_2(1)\}}=37,x_2(x)=2 F3(10)=max{g3(0)+F2(10),g3(1)+F2(9),g3(2)+F2(6),g3(3)+F2(1)}=37,x2(x)=2
备忘录:
因此,问题的解是:在 x 1 = 1 , x 2 = 2 , x 3 = 2 x_1=1,x_2=2,x_3=2 x1=1,x2=2,x3=2时,得到 g 1 ( x 1 ) + g 2 ( x 2 ) + g 3 ( x 3 ) g_1(x_1)+g_2(x_2)+g_3(x_3) g1(x1)+g2(x2)+g3(x3)得到最大值37
7、设A=< X 1 , X 2 , … , X n X_1, X_2, …, X_n X1,X2,…,Xn> 是n个不等的整数的序列,A的一个单调递增子序列是序列< X i 1 , X i 2 , … , X i k X_{i1}, X_{i2}, …, X_{ik} Xi1,Xi2,…,Xik > 使得 i 1 < i 2 < … < i k i1
解析:因为需要求最长,并且有条件限制,因此可以用动态规划试试。
使用动态规划技术,对 i = 1 , 2 , 3... n i=1,2,3...n i=1,2,3...n(其中i表示元素的序号),考虑以 x i x_i xi作为最长单调子序列的最后项(结尾),使用 C [ i ] C[i] C[i]表示以 x i x_i xi为最长子序列的最后项的长度。
则:
C [ i ] = m a x { 1 + C [ j ] } C[i]=max\{1+C[j]\} C[i]=max{1+C[j]},其中i>j>=1
否则(如果不存在i>i>=1,使得 ( x i > x j ) (x_i>x_j) (xi>xj)或i=1时), C [ i ] = 1 C[i]=1 C[i]=1
使用 k [ i ] = j k[i]=j k[i]=j表示当 C [ i ] C[i] C[i]取得最大值的时候,j的取值
对于给定实例:A= <2, 8, 4, -4, 5, 9, 11>
C[1]=1,k[1]=0
C [ 2 ] = m a x { 1 + C [ 1 ] } = 2 , k [ 2 ] = 1 C[2]=max\{ 1+C[1]\}=2,k[2]=1 C[2]=max{1+C[1]}=2,k[2]=1
C [ 3 ] = m a x { 1 + C [ 1 ] } = 2 , k [ 3 ] = 1 C[3]=max\{ 1+C[1]\}=2,k[3]=1 C[3]=max{1+C[1]}=2,k[3]=1
C [ 4 ] = 1 , k [ 4 ] = 0 C[4]=1,k[4]=0 C[4]=1,k[4]=0
C [ 5 ] = m a x { 1 + C [ 1 ] , C [ 3 ] + 1 , C [ 4 ] + 1 } = 3 , k [ 5 ] = 3 C[5]=max\{ 1+C[1],C[3]+1,C[4]+1\}=3,k[5]=3 C[5]=max{1+C[1],C[3]+1,C[4]+1}=3,k[5]=3
C [ 6 ] = m a x { 1 + C [ 1 ] , 1 + C [ 2 ] , 1 + C [ 3 ] , 1 + C [ 4 ] , 1 + C [ 5 ] } = 4 , k [ 6 ] = 5 C[6]=max\{ 1+C[1],1+C[2],1+C[3],1+C[4],1+C[5]\}=4,k[6]=5 C[6]=max{1+C[1],1+C[2],1+C[3],1+C[4],1+C[5]}=4,k[6]=5
C [ 7 ] = m a x { 1 + C [ 1 ] , 1 + C [ 2 ] , 1 + C [ 3 ] , 1 + C [ 4 ] , 1 + C [ 5 ] , 1 + C [ 6 ] } = 5 , k [ 7 ] = 6 C[7]=max\{ 1+C[1],1+C[2],1+C[3],1+C[4],1+C[5],1+C[6]\}=5,k[7]=6 C[7]=max{1+C[1],1+C[2],1+C[3],1+C[4],1+C[5],1+C[6]}=5,k[7]=6
因此,最长子序列长度为5,最长递增子序列为<2,4,5,9,11>
因为,对于每个i,要检索比i小的所有j,需要O(n)的时间,i的取值有n种,因此,时间复杂度为O( n 2 n^2 n2)
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
A[i] | 2 | 8 | 4 | -4 | 5 | 9 | 11 |
C[i] | 1 | 1 | 1 | 1 | 3 | 4 | 5 |
K[i] | 0 | 1 | 1 | 0 | 3 | 5 | 6 |
8、有n个底面为长方形(各长方形长度表示为 li)的货柜需租用库房存放。如果货柜都需放在地面,且所有货柜的底面宽度等于库房的宽度,库房总长度 D满足:li<=D, ∑ \sum ∑li>D。 再设第i号货柜的仓储效益是 vi, 请问如何放入库房可以获得最大收益?设计求解算法及伪码。(0-1背包问题)
解析:类似于0-1背包问题,库房的长度相当于背包的容量,每个货柜的效益相当于每个背包的价值:
m a x ∑ i = 1 n v i ∗ x i max \sum_{i=1}^nv_i*x_i max∑i=1nvi∗xi
∑ l i ∗ x i < = D \sum l_i*x_i<=D ∑li∗xi<=D
令 F k ( y ) F_k(y) Fk(y)表示只允许装前k个货柜,库房长度为y时 的效益最大值:
F k ( y ) = m a x { F k − 1 ( y − l k ) + v k , F k − 1 ( y ) } , l k < = y < = D F_k(y)=max\{ F_{k-1}(y-l_k)+v_k,F_{k-1}(y)\},l_k<=y<=D Fk(y)=max{Fk−1(y−lk)+vk,Fk−1(y)},lk<=y<=D
F k ( y ) = F k − 1 ( y ) , l k > y F_k(y)=F_{k-1}(y),l_k>y Fk(y)=Fk−1(y),lk>y
F 1 ( y ) = v i , 当 l 1 < = y 时 , 0 , 当 l i > y 时 F_1(y)=v_i,当l_1<=y时,0,当l_i>y时 F1(y)=vi,当l1<=y时,0,当li>y时
9、Dijkstra算法要求有向图的边的权是非负实数,请举出反例说明,对于某些含有负数边权的有向 图,Dijkstra不能得到正确的解
解析:Dijkstra最短路径算法对负权图失效,不存在最短路径。
10、给定n个集合 A 1 , . . . A n A_1,...A_n A1,...An,每个集合都由连续的正整数构成,即:
A i = { x ∣ a i < = x < = b i } , a i , x , b i ∈ Z + i = 1 , 2 , . . . . n A_i=\{ x|a_i<=x<=b_i\},a_i,x,b_i∈Z^+ i=1,2,....n Ai={x∣ai<=x<=bi},ai,x,bi∈Z+i=1,2,....n
设计一个算法求最小的集合S,使得对于每个i=1,2…n,| S ∩ A i ≠ ∅ S∩A_i\not =∅ S∩Ai=∅|,即每个 A i A_i Ai至少包含有S中的一个数
解析:这道题目类似于活动问题,都是要找出相容的活动,并把相容的 活动放入结果集中。在本题中,需要找出相容(一个集合的结束值元素大于另一个集合的开始值元素,则称这两个集合相容)的集合,将这些集合的结束值放到结果集中。
使用贪心算法,对 b i b_i bi从小到大进行排序(正如活动问题中按照结束时间由早到晚进行排序),将 b i b_i bi放入S。将 b i b_i bi记作当前的测试点x,按照顺序依次检查 A 2 , . . . A n A_2,...A_n A2,...An的 a 1 a_1 a1,若 a 1 < = x a_1<=x a1<=x,说明S已包含该集合 A i A_i Ai中的某个元素(不相容),否则,说明这两个集合不相容,则把 b i b_i bi加入到S中,并将测试点x赋值新的 b i b_i bi,直到测试完所有集合为止,得到的S即为所求解。
11、最小重量机器设计问题: 某设备需4种配件,每种一件,且有三个供应商提供这些配件。下表给出相关的价格和每种配件的重量;从中选择4种配件(的供应商),使得总价值不超过120,且总重量最轻。
产品和供应商信息表:
解析:最后问题的解是一个向量(每一种零件选择的对应厂商),设解向量为< x 1 , x 2 . . . . x k x_1,x_2....x_k x1,x2....xk>, x i = j x_i=j xi=j表示第i号零件由j号供应商供货,并且是组合优化问题,也满足多米诺性质,因此可以使用回溯算法。
目标函数:
m i n ∑ w ( x i ) min \sum w(x_i) min∑w(xi)
∑ v ( x i ) < = 120 , 1 < = i < = 4 \sum v(x_i)<=120, 1<=i<=4 ∑v(xi)<=120,1<=i<=4
搜索树:4层,每层边代表一种零件,权值代表供应商编号。
界函数:目前得到的最优解的重量
代价函数:节点< x 1 , x 2 , . . . . x k x_1,x_2,....x_k x1,x2,....xk>表示已经选择了前k号零件的供应商,正在处理k+1号零件
∑ i = 1 k w ( x i ) + ∑ j = k + 1 n w ( x j ) \sum_{i=1}^kw(x_i)+\sum_{j=k+1}^nw(x_j) ∑i=1kw(xi)+∑j=k+1nw(xj)
12、子集和问题. 设n个不同的正数构成集合S,求出使得和为某数M的S的所有子集。
解析:类似于0-1背包问题。设S={ a 1 , a 2 , . . . . a n a_1,a_2,....a_n a1,a2,....an},求S满足条件 ∑ a i ∈ A a i = M \sum_{a_i∈A}a_i=M ∑ai∈Aai=M的所有子集A。用回溯法。
解向量 < x 1 , x 2 . . . . . x n > , x i = 0 , 1
(分支的条件是前面选择进入结果集的元素和小于M,并且后面要加入的元素值要小于能加入的值)
13、
解析:
对于递推方程 T ( n ) = 7 T ( n / 2 ) + n 2 , a = 7 , b = 2 , f ( n ) = n 2 , n l o g b a = n l o g 2 7 T(n)=7T(n/2)+n^2,a=7,b=2,f(n)=n^2,n^{log_b^a}=n^{log_2^7} T(n)=7T(n/2)+n2,a=7,b=2,f(n)=n2,nlogba=nlog27,因此, T ( n ) = Θ ( n l o g 2 7 ) T(n)=\Theta(n^{log_2^7}) T(n)=Θ(nlog27)
对于递推方程 W ( n ) W(n) W(n)也使用主定理, W ( n ) = Θ ( n l o g 4 a ) W(n)=\Theta(n^{log_4^a}) W(n)=Θ(nlog4a)
若使 l o g 4 a < l o g 2 7 log_4^a
l o g 4 a = l o g 2 a l o g 2 4 = l o g 2 a 2 < l o g 2 7 log_4^a=\frac{log_2^a}{log_24}=\frac{log_2^a}{2}
解析:类似于芯片测试问题,使用分治策略。
算法设计思想:采用分治策略。若n<3,将剩下的硬币与之前比较拿走的硬币相比较,不等的就是不合格的硬币。否则,将n个硬币分成大致相等的3份,如果n%3!=0,则令两份少的相等,取两份相等的放到天平上,如果天平不平衡,说明不合格的硬币在这两堆之中,直接将这两堆合并再进行下一次的分组,否则,说明不合格的硬币在另外一堆,递归处理,直到n<3为止。
伪代码:
算法Coin(A,n) //A是n个硬币的集合
该算法的递推方程:
T ( n ) = T ( 2 n / 3 ) + O ( 1 ) T(n)=T(2n/3)+O(1) T(n)=T(2n/3)+O(1) 每一次划分都划分成了原问题规模的2/3,还需要加上划分的工作量
T ( 1 ) = 0 , T ( 2 ) = 1 T(1)=0,T(2)=1 T(1)=0,T(2)=1
15、设字符集S,其中8个字符A,B,C,D,E,F,G,H的频率是 1 100 , 1 100 , 2 100 , 3 100 , 5 100 , 8 100 , 13 100 , 21 100 \frac{1}{100},\frac{1}{100},\frac{2}{100},\frac{3}{100},\frac{5}{100},\frac{8}{100},\frac{13}{100},\frac{21}{100} 1001,1001,1002,1003,1005,1008,10013,10021,设计这8个字符的Hufffman树和编码
解析:为了方便画图,我们将上面的频率都乘100
16、概述回溯算法的有关概念
17、总结排序算法的复杂性
排序 | 最好时间复杂度 | 平均时间复杂度 | 最差时间复杂度 | 空间复杂度 | 是否稳定 | 算法比较优秀的情况 |
---|---|---|---|---|---|---|
冒泡排序 | O(n) | O( n 2 n^2 n2) | O( n 2 n^2 n2) | O(1) | 是 | 当待排序数组基本有序,个数较少 |
选择排序 | O( n 2 n^2 n2) | O( n 2 n^2 n2) | O( n 2 n^2 n2) | O(1) | 是 | 与平均时间复杂度一样 |
快速排序 | O(nlogn) | O(nlogn) | O( n 2 n^2 n2) | O(logn)~O(n) | 否 | |
插入排序 | O(n) | O( n 2 n^2 n2) | O( n 2 n^2 n2) | O(1) | 是 | 当待排序数组基本有序,个数较少 |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 否 | |
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 是 | 执行效率与要排序的原始数组的有序程度无关,所以其时间复杂度是非常稳定的,不管是最好情况、最坏情况,还是平均情况,时间复杂度都是O(nlogn). |
希尔排序 | O( n 1.3 n^{1.3} n1.3) | O(nlogn)~O( n 2 n^2 n2) | O( n 2 n^2 n2) | O(1) | 否 |
18、设计一个动态规划算法计算下面的数列中的F(n):
F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2),n>=2
基本思想:将privious(F(n))的值保存起来,因为计算后面的F(n)需要用到前面计算的结果。
1. arr[0]<-0,arr[1]<-1;
2. for i<- 2 to n do
3. arr[i]<-arr[i-1]+arr[i-2];
19、设计一个算法,对于一个给定的包含n个整数的集合S和另一个给定的整数x,该算法可以在O(nlogn)时间内确定S中是否存在两个元素,使得它们的和恰为x
解析:由于算法的时间复杂度为O(nlogn),则可以很容易想到排序算法中有很多O(nlogn)的算法,如快速排序。
基本思路:可以使用快速排序算法对集合S进行从小到大的排序,令i=0,j=length(S)-1,即i和j分别指向集合S的首尾,比较S[i]+S[j]与x的大小,若S[i]+S[j]
分析算法的时间复杂度:排序算法的时间复杂度为O(nlogn),遍历数组O(n),比较O(n),因此算法的复杂度为O(nlogn)+O(n)+O(n)-》O(nlogn),因此,满足题目要求。
#include <cstdio>
#include <cstdlib>
#include <cstring>
//快排 时间复杂度O(nlogn)
void quick_sort(int* arr, int l, int r) {
if (l >= r) return;
while (l < r) {
int x = l, y = r;
int z = arr[l];
do {
while (x <= y && arr[x] < z) x++;
while (x <= y && arr[y] > z) y--;
if (x <= y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
x++, y--;
}
} while (x <= y);
quick_sort(arr, l, y);
l = x;
}
}
//判断是否满足条件 O(n)时间复杂度
bool is_ok(int* A, int x, int len) {
quick_sort(A, 0, len - 1);
int i = 0, j = len - 1;
while (i < j) {
if (A[i] + A[j] == x) return true;
else if (A[i] + A[j] > x) j--;
else i++;
}
return false;
}
int main() {
int A[8] = {3, 41, 52, 26, 38, 57, 9, 49};
int x;
while (scanf("%d", &x) != EOF) {
printf("%d\n", is_ok(A, x, 8));
}
return 0;
}
21、分治策略的典型例子:芯片测试
有n片芯片,已知好芯片至少比坏芯片多1片,如何实现找出一片好芯片(要求使用最少的测试次数)。
基本思想:将n片芯片分成 ⌊ n 2 ⌋ \left \lfloor \frac{n}{2}\right \rfloor ⌊2n⌋组,让每两两进行测试,如果测试结果为1好1坏或两个都是坏,则直接丢弃这一组,如果两个都报告好,那么从该组中随机选择一片。不断重复上述步骤。当n=3时,任取两片进行测试,报告1好1坏或2坏,都取未测试的芯片,若报告2好,则随机取一个。若n=2或n=1,随机取一片即为好芯片。
时间复杂度:O(n)
W ( n ) = W ( n / 2 ) + O ( n ) W(n)=W(n/2)+O(n) W(n)=W(n/2)+O(n)
W ( 3 ) = 1 , W ( 1 ) = W ( 2 ) = 0 W(3)=1,W(1)=W(2)=0 W(3)=1,W(1)=W(2)=0
伪代码:
1. k<-n
2. while k>3 do
3. 将芯片分成k/2组 //如有轮空芯片,单独测试,根据情况丢弃或保留
4. for i<-1 to k/2 do
5. if 2片好,则任取一片留下
6. else 2片同时丢弃
7. k<- 此时剩下的芯片数
8. if k=3
9. then 任取2片芯片测试
10. if 2好,任取一片被测芯片
11. else 取未测试的芯片
12. if k=1或k=2,任取一片
22、经典的分治例子:幂乘问题
输入:a为给定实数,n为自然数
输出: a n a^n an
该分治问题的设计思想:若n是偶数,则只要计算 a n / 2 a^{n/2} an/2就可以了,剩下的 a n / 2 a^{n/2} an/2可以直接照搬之前的结果。若n是奇数,则只需要计算 a n − 1 / 2 a^{n-1/2} an−1/2就可以了,然后最后结果还要多乘一个a。
时间复杂度: W ( n ) = Θ ( l o g n ) W(n)=\Theta(logn) W(n)=Θ(logn)
W ( n ) = W ( n / 2 ) + Θ ( 1 ) W(n)=W(n/2)+\Theta(1) W(n)=W(n/2)+Θ(1)
23、典型的动态规划问题:投资问题
5万元钱,4项目投资, f i ( x ) f_i(x) fi(x):将x元投给第i个项目的效益。求使得总效益最大的投资方案。
效益函数如下:
解析:
k:对项目1,2,…k的投资
x:投资总钱数不超过x
F k ( x ) F_k(x) Fk(x):x元钱投给前k个项目的最大效益。
令 x k ( x ) x_k(x) xk(x)为当 F k ( x ) F_k(x) Fk(x)取最大值时, x k x_k xk的取值
因此,递推方程和边界条件为:
F k ( x ) = m a x { f k ( x k ) + F k − 1 ( x − x k ) } , k > 1 , 0 < = x k < = x F_k(x)=max\{ f_k(x_k)+F_{k-1}(x-x_k)\},k>1,0<=x_k<=x Fk(x)=max{fk(xk)+Fk−1(x−xk)},k>1,0<=xk<=x
F 1 ( x ) = f 1 ( x ) F_1(x)=f_1(x) F1(x)=f1(x)
当k=1时:
F 1 ( 0 ) = 0 , F 1 ( 1 ) = 11 , F 1 ( 2 ) = 12 , F 1 ( 3 ) = 13 , F 1 ( 4 ) = 14 , F 1 ( 5 ) = 15 F_1(0)=0,F_1(1)=11,F_1(2)=12,F_1(3)=13,F_1(4)=14,F_1(5)=15 F1(0)=0,F1(1)=11,F1(2)=12,F1(3)=13,F1(4)=14,F1(5)=15
当k=2时:
F 2 ( 0 ) = 0 , F 2 ( 1 ) = m a x { f 2 ( 0 ) + F 1 ( 1 ) , f 2 ( 1 ) + F 1 ( 0 ) } = 11 x 2 ( 1 ) = 0 F_2(0)=0,F_2(1)=max\{ f_2(0)+F_1(1),f_2(1)+F_1(0)\}=11x_2(1)=0 F2(0)=0,F2(1)=max{f2(0)+F1(1),f2(1)+F1(0)}=11x2(1)=0
F 2 ( 2 ) = m a x { f 2 ( 0 ) + F 1 ( 2 ) , f 2 ( 1 ) + F 1 ( 1 ) , f 2 ( 2 ) + F 1 ( 0 ) } = 12 , x 2 ( 2 ) = 0 F_2(2)=max\{ f_2(0)+F_1(2),f_2(1)+F_1(1),f_2(2)+F_1(0)\}=12,x_2(2)=0 F2(2)=max{f2(0)+F1(2),f2(1)+F1(1),f2(2)+F1(0)}=12,x2(2)=0
F 2 ( 3 ) = m a x { f 2 ( 0 ) + F 1 ( 3 ) , f 2 ( 1 ) + F 1 ( 2 ) , f 2 ( 2 ) + F 1 ( 1 ) , f 2 ( 3 ) + F 1 ( 0 ) } = 16 , x 2 ( 3 ) = 2 F_2(3)=max\{ f_2(0)+F_1(3),f_2(1)+F_1(2),f_2(2)+F_1(1),f_2(3)+F_1(0)\}=16,x_2(3)=2 F2(3)=max{f2(0)+F1(3),f2(1)+F1(2),f2(2)+F1(1),f2(3)+F1(0)}=16,x2(3)=2
F 2 ( 4 ) = m a x { f 2 ( 0 ) + F 1 ( 4 ) , f 2 ( 1 ) + F 1 ( 3 ) , f 2 ( 2 ) + F 1 ( 2 ) , f 2 ( 3 ) + F 1 ( 1 ) , f 2 ( 4 ) + F 1 ( 0 ) } = 21 , x 2 ( 4 ) = 3 F_2(4)=max\{ f_2(0)+F_1(4),f_2(1)+F_1(3),f_2(2)+F_1(2),f_2(3)+F_1(1),f_2(4)+F_1(0)\}=21,x_2(4)=3 F2(4)=max{f2(0)+F1(4),f2(1)+F1(3),f2(2)+F1(2),f2(3)+F1(1),f2(4)+F1(0)}=21,x2(4)=3
F 2 ( 5 ) = m a x { f 2 ( 0 ) + F 1 ( 5 ) , f 2 ( 1 ) + F 1 ( 4 ) , f 2 ( 2 ) + F 1 ( 3 ) , f 2 ( 3 ) + F 1 ( 2 ) , f 2 ( 4 ) + F 1 ( 1 ) , f ( 5 ) + F 1 ( 0 ) } = 26 , x 2 ( 5 ) = 4 F_2(5)=max\{ f_2(0)+F_1(5),f_2(1)+F_1(4),f_2(2)+F_1(3),f_2(3)+F_1(2),f_2(4)+F_1(1),f_(5)+F_1(0)\}=26,x_2(5)=4 F2(5)=max{f2(0)+F1(5),f2(1)+F1(4),f2(2)+F1(3),f2(3)+F1(2),f2(4)+F1(1),f(5)+F1(0)}=26,x2(5)=4
同理,当k=3,4的时候如此。
备忘录:
因此,5万元分给4个项目的最大效益为61万元。每个项目的分配方案为:<1,0,3,1>
备忘录中有m行n列:时间复杂度分析:W(n)= O ( n m 2 ) O(nm^2) O(nm2)
24、动态规划求解背包问题
物品n种,每种的重量和价值分别为 w i , v i w_i,v_i wi,vi,如果背包最大限重为b,每种物品可以放多个,怎么选择放入的物品使得背包价值最大?
假设n=4,b=10,
v 1 = 1 , v 2 = 3 , v 3 = 5 , v 4 = 9 v_1=1,v_2=3,v_3=5,v_4=9 v1=1,v2=3,v3=5,v4=9
w 1 = 2 , w 2 = 3 , w 3 = 4 , w 4 = 7 w_1=2,w_2=3,w_3=4,w_4=7 w1=2,w2=3,w3=4,w4=7
解析:
目标函数: m a x ∑ i = 1 n v i x i max\sum_{i=1}^nv_ix_i max∑i=1nvixi
约束条件: ∑ i = 1 n w i x i < = b , x i ∈ N \sum_{i=1}^nw_ix_i<=b,x_i∈N ∑i=1nwixi<=b,xi∈N
k:考虑对物品1,2,…k的选择
y:背包总重量不超过y
F k ( y ) F_k(y) Fk(y):表示前k种物品,总重不超过y背包达到的最大价值
F k ( y ) = m a x { F k − 1 ( y − w k ) + v k , F k − 1 ( y ) } F_k(y)=max\{ F_{k-1}(y-w_k)+v_k,F_{k-1}(y)\} Fk(y)=max{Fk−1(y−wk)+vk,Fk−1(y)}
F 0 ( y ) = 0 , 0 < = y < = b , F k ( 0 ) = 0 , 0 < = k < = n F_0(y)=0,0<=y<=b,F_k(0)=0,0<=k<=n F0(y)=0,0<=y<=b,Fk(0)=0,0<=k<=n
F 1 ( y ) = ⌊ y / w 1 ⌋ v 1 , F k ( y ) = − ∞ , y < 0 F_1(y)=\left \lfloor y/w_1 \right \rfloor v_1,F_k(y)=-\infty,y<0 F1(y)=⌊y/w1⌋v1,Fk(y)=−∞,y<0
时间复杂度为O(nb)
25、动态规划之最长公共子序列问题
X:A B C B D A B
Y:B D C A B A
最长公共子序列为:B C B A ,长度为4
令X与Y的子序列 X i = < x 1 , x 2 . . . . x i > , Y j = < y 1 , y 2 , . . . . y j > X_i=
C [ i , j ] = 0 , 若 i = 0 或 j = 0 C[i,j]=0,若i=0或j=0 C[i,j]=0,若i=0或j=0
C [ i , j ] = 1 + C [ i − 1 , j − 1 ] , 若 i , j > 0 , x i = x j C[i,j]=1+C[i-1,j-1],若i,j>0,x_i=x_j C[i,j]=1+C[i−1,j−1],若i,j>0,xi=xj
C [ i , j ] = m a x { C [ i − 1 , j ] , C [ i , j − 1 ] } , 若 i , j > 0 , x i ≠ x j C[i,j]=max\{ C[i-1,j],C[i,j-1]\},若i,j>0,x_i\not=x_j C[i,j]=max{C[i−1,j],C[i,j−1]},若i,j>0,xi=xj
时间复杂度:O(mn)
26、动态规划之最大字段和问题:
C [ i ] C[i] C[i]表示为以A[i]为最大子段结尾的最大子段和
递推方程:
C [ i ] = m a x { A [ i ] , A [ i ] + C [ i − 1 ] } , i = 1 , 2 , . . . n C[i]=max\{ A[i],A[i]+C[i-1]\},i=1,2,...n C[i]=max{A[i],A[i]+C[i−1]},i=1,2,...n
C[1]=A[1],若A[1]>0
C[1]=0 否则
解: O P T ( A ) = m a x C [ i ] , 1 < = i < = n OPT(A)=max{C[i]},1<=i<=n OPT(A)=maxC[i],1<=i<=n
时间复杂度为O(n)
27、对于下列数组使用快速排序算法,写出每一次划分的结果。并简单描述快速排序的基本思想
快速排序的基本思想:(是一种分治策略)将待排序的数组经过一趟排序分成独立的两个部分,一个部分比关键字小,一个部分比关键字大,然后可以分别对这两部分的记录进行排序,以达到整个数组的有序。
第一次划分:2 1 3 4 8 7 6 5
第二次划分:1 2 3 4 5 7 6 8
第三次划分:1 2 3 4 5 7 6 8
第四次划分:1 2 3 4 5 6 7 8
28、在下面的有向图中应用算法Dijstra。假设顶点1是起始顶点。
从节点1出发到节点1,2,3,4,5的最短距离为0,2,5,11,10,14
29、各种关于算法的基本概念:
分治策略的基本思想:
使用动态优化算法的原则是:具有最优子结构性质(某个问题的最优解包含子问题的最优解。)
设计动态规划算法的主要步骤:
动态规划算法的基本要素是最优子结构性质和子问题重叠性质。
贪心算法的基本要素是贪心选择性质和最优子结构性质。
请简述你对算法复杂性概念的认识:
算法复杂性是指算法运行所需要计算机资源的量。需要时间资源的量称为时间复杂性,需要的空间资源的量,称为空间复杂性。
时间复杂性和空间复杂性是衡量算法效率的两个重要指标。一般的,我们认为时间复杂度越小,算法的效率越高;空间复杂度越小,算法的效率越高。但是在实际中,我们很难保证一个算法既有好的时间复杂度又有好的空间复杂度,所以评判一个算法的好坏,还需要在具体环境中。若环境对空间的要求很苛刻,那么我们往往会牺牲时间换空间,反之亦如此。
在算法复杂性研究中,衡量输入问题的大小的常用方法有哪些?
最优算法的定义是什么?请举出一个最优算法的例子说明。
如果可以证明一个问题I的算法必然是 Ω ( f ( n ) ) Ω(f(n)) Ω(f(n))的,那么在 O ( f ( n ) ) O(f(n)) O(f(n))时间内解决问题I的算法称为问题I的最优算法。对n大小的数组排序的问题是 Ω ( n l o g n ) Ω(nlogn) Ω(nlogn),而归并排序算法的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn),因此,归并排序是基于比较排序的最优算法。
请给出回溯算法的主要步骤和适用范围:
回溯算法适用于搜索问题和优化问题。
解析:
回溯算法的一般步骤:
请给出衡量算法性能的几个标准:
正确性、易读性、健壮性、算法的时间复杂度和空间复杂度。
在算法复杂性研究中,基本运算的概念是什么?不同问题中常用的基本运算是什么?
解析:如果在一个算法中一个元运算具有最高频率,所有其他的元运算频率均在他的频度的常数倍内,则称这个元运算是基本运算。
常选取的基本运算有: