当前位置:
文档之家› 第2章 递归与分治_作业答案
第2章 递归与分治_作业答案
• 练习3:分析Strassen矩阵乘法在时间效率上有何 改进,为什么?
• Strassen矩阵乘积分治算法中,用了7次对于n/2阶 矩阵乘积的递归调用和18次n/2阶矩阵的加减运算。 由此可知,该算法的所需的计算时间T(n)满足如 下的递归方程: O1 n2
T n 2 7 T n / 2 O n
具体执行过程:求最大值
0 1 2 3 4 5 6 7 8 9 10 11 12 13 24 -13 29 113 87 65 -9 36 14 76 44 83 67 5 0 1 2 3 4 5 6 24 -13 29 113 87 65 -9 0 1 2 3 24 -13 29 113 0 1 24 -13 2 3 29 113 4 5 6 87 65 -9 7 8 9 10 11 12 13 36 14 76 44 83 67 5 7 8 9 10 36 14 76 44 7 8 36 14 7 36 9 10 76 44 11 12 13 83 67 5 11 12 83 67 11 83 12 67 13 5
课后练习
• 练习1:给定数组a[0:n-1], 1. 试设计一个分治法算法,找出a[0:n-1]中元素最 大值和最小值; 2. 写出该算法时间函数T(n)的递推关系式; 3. 分析该算法的时间复杂度和空间复杂度。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 24 -13 29 113 87 65 -9 36 14 76 44 83 67 5
课后练习
• 练习2:分析如下时间函数的复杂度,并说明 原因。 1. 利用递归树说明以下时间函数的复杂度:
O(1) T ( n) 3T ( n ) O( n) 4 n1 n1
2. 利用主定理说明以下时间函数的复杂度:
T(n) = 16T(n/4) + n
T(n) = T(3n/7) + 1
n2
T(n)=O(nlog7)≈O(n2.81)
较大的改进
课后练习
• 练习4:划出下列序列在快速排序过程中一次 划分的具体步骤。
21 25 49 25* 16 08
一次划分的过程
初始关键字
pivotkey 21 low 08 08 08 08 08 25 49 25* 16 08 high 21 high 25
T(n) = 3T(n/4) + nlogn
• 练习2:分析如下时间函数的复杂度, T ( n) 3T ( n ) O( n) 4 n1 n1
• 递归树的高度为:log4n+1;
• 除去叶子结点,树有log4n层,每层结点总数为:
时间复杂性分析
• 该算法的时间函数的递推式为:
O(1) n1 T (n) n T ( ) O(1) n 1 2
• 该算法的时间复杂度为:O(log2n)
课后练习(选做)
• 练习7:假设你正在为一个小的投资公司咨询,他们有下 面类型的问题想要一次又一次的求解。这个问题的一个 典型实例如下所述。他们正在做一项模拟,在这项模拟 中他们从过去的某点开始对一只给定的股票连续看n天。 让我们把这些天记为数i=1,2,…,n;对每天i,他们有当天 这只股票每股的价格p(i)(简单起见,假设这个价格在一 天之内是固定的)。假设在这个时间区间内,某天他们 想买1000股并且在以后的某天卖出所有这些股。他们想 知道:为了挣到最多的钱,他们应该什么时候买并且什 么时候应该卖?
• 要求:
– 设计算法; – 写出该算法时间函数T(n)的递推关系式; – 分析其时间复杂度和空间复杂度。
关于集合划分问题的分析
• 例如:集合 { 1, 2, 3 } 有五个划分
– { {1}, {2}, {3} }, – { {1, 2}, {3} },{ {1, 3}, {2} },{ {1}, {2, 3} }, – { {1, 2, 3} }。 • 算法设计要求:给定正整数n 和m,计算出n 个元素的集 合{1,2,., n }可以划分为多少个不同的由m 个非空子集组成 的集合。 • 数据输入:由文件input.txt 提供输入数据。文件的第1 行 是元素个数n 和非空子集数m。 • 结果输出:程序运行结束时,将计算出的不同的由m个非 空子集组成的集合数输出到文件output.txt 中。
– 分析该算法的时间复杂性。
问题分析
• 何为“单峰”?
– 对于某个在1与n之间的下标p,数组项的值增 加到A中的位置p,然后剩下的过程减少直到 位置n; – 即在A[1]到A[n]的n个数中,只有一个极大值 A[p]; – A[p]前的元素均小于A[p],并按升序排列;
– A[p]后的元素均小于A[p],并按降序排列。
• 则算法是在下面三个可能的解中最好的: – S上的最优解 – S’上的最优解 – p(j)-p(i)的最大值,对所有的i∈S且j∈S’ • 前两个选择中的每一个在T(n/2)时间内被递归地计算;
• 第三个选择通过找S中的最小与S’中的最大而计算,该操 作需要O(n)时间。
• 则运行时间的递推关系式是: T ( n) 2T ( n ) O( n) 2 • 则算法的时间复杂度为:O(nlog2n)。
问题分析、举例说明
• 利用分治策略设计一个算法。
• 举例:
– 假设n=3, p(1)=9, p(2)=1, p(3)=5. 那么应该得出“2买,3 卖”的结论。即,在第2天买并且在第3天卖意味着每股 将挣4美元,是这个期间最大的收益。 • 问题分析: – 存在一个简单的算法,时间复杂度是O(n2):对所有的 买天/卖天构成的对进行尝试,看看哪个对能使用户挣 到最多的钱。 – 假设在第i天买、第j天卖可以获得最大收益:最优解。
一次交换
二次交换
三次交换
四次交换 完成一趟排序
25 49 low 21 49 low 16 49
16 16
25* 16
25*
16 high 25* 21 25 high low 21 25* 49 25 low high 21 25* 49 25
low high
课后练习
• 练习5:算法实现题2-8(教材第42页)集合划 分问题。
• 如果要求F(4,2)该怎么办呢?
A. 往①里添一个元素{4},得到{{1,2,3},{4}}
B. 往②里的任意一个子集添一个4,得到 {{1,2,4},{3}},{{1,2},{3,4}},
{{1,3,4},{2}},{{1,3},{2,4}},
{{2,3,4},{1}},{{2,3},{1,4}} ∴F(4,2)=F(3,1)+2*F(3,2)=1+2*3=7
• 递归公式:
– 设n个元素的集合可以划分为F(n,m)个不同的由 m个非空子集组成的集合。 F(n,m) = 1, when n=0, n=m, n=1, or m=1 F(n,m) = 0, when n<m 否则 F(n,m)=F(n-1,m-1)+m*F(n-1,m)
• 考虑3个元素的集合,可划分为 – ① 1个子集的集合:{{1,2,3}} – ② 2个子集的集合:{{1,2},{3}},{{1,3},{2}}, {{2,3},{1}} – ③ 3个子集的集合:{{1},{2},{3}} ∴F(3,1)=1;F(3,2)=3;F(3,3)=1;
课后练习(选做)
• 练习6:假设有n个项的数组A,每个项具有一个 不同的数。告诉你值A[1],A[2],…,A[n]的序列是单 峰的:对于某个在1与n之间的下标p,数组项的值 增加到A中的位置p,然后剩下的过程减少直到位 置 n。 • 要求:
– 利用分治策略设计一个算法,读尽可能少的元 素,找到这个“顶峰”元素p。
c2 n (1 3 ( 3 ) 2 ( 3 )log4 n1 ) 4 4 4
• 最后一层叶子结点数: 3log4 n nlog4 3
换底公式
2. 利用主定理说明以下时间函数的复杂度:
T(n) = 16T(n/4) + n T(n) = T(3n/7) + 1 T(n) = 3T(n/4) + nlogn 定理(主定理): a≥1且b>1是常数, f(n)是一个函数,T(n)由 如下的递推式定义:T(n)=aT(n/b)+f(n),式中,n/b指n/b或 n/b,则T(n)有如下的渐近界: (1)若对于某常数є>0,有f(n)=O(nlogba-є),则T(n)=(nlogba); (2)若f(n)=(nlogba ),则T(n)=(nlogbalogn); (3)若对于某常数є>0,有f(n)=(nlogba+є ),且对于某个常数 c<1和所有足够大的n,有af(n/b)≤cf(n),则T(n)=(f(n))。
• 如果A[n/2]比A[n/2-1]和A[n/2+1]都大,顶峰项实际上就等 于A[n/2]。
具体算法:伪代码
int Danfeng(int A[], int m, int n) { //求单峰数组中的顶峰值 int k=(m+n)/2; if(k==m&&k==n) return A[k]; if(A[k-1]<A[k]&&A[k]>A[k+1]) return A[k]; else { if(A[k-1]<A[k]&&A[k]<A[k+1]) Danfeng(A[], k+1, n); if(A[k-1]>A[k]&&A[k]>A[k+1]) Danfeng(A[], m, k-1); } }
具体算法:伪代码
int MaxProfit(int p[], int m, int n) { //求第m到第n天内一次买卖股票的最大收益 int i=m, j=(m+n)/2+1; //在第i天买入股票,并在第j天卖出股票 int k; int max1, max2, max3; //三个可能的最优解 max1=MaxProfit(p, m, (m+n)/2); // S上的最优解 max2=MaxProfit(p, (m+n)/2+1, n); // S’上的最优解 for(k=m+1;k<=(m+n)/2;k++) //求最小p(i) if(p(i)>p(k)) p(i)=p(k); for(k=(m+n)/2+2;k<=n;k++) //求最大p(j) if(p(j)<p(k)) p(j)=p(k); max3=p(j)-p(i); return 最大值(max1, max2, max3); } //最优解