计算机算法设计与分析(第4版) 王晓东习题解答
- 格式:pdf
- 大小:473.44 KB
- 文档页数:29
《计算机算法设计与分析》习题及答案一.选择题1、二分搜索算法是利用( A )实现的算法。
A、分治策略B、动态规划法C、贪心法D、回溯法2、下列不是动态规划算法基本步骤的是( A )。
A、找出最优解的性质B、构造最优解C、算出最优解D、定义最优解3、最大效益优先是( A )的一搜索方式。
A、分支界限法B、动态规划法C、贪心法D、回溯法4. 回溯法解旅行售货员问题时的解空间树是( A )。
A、子集树B、排列树C、深度优先生成树D、广度优先生成树5.下列算法中通常以自底向上的方式求解最优解的是( B )。
A、备忘录法B、动态规划法C、贪心法D、回溯法6、衡量一个算法好坏的标准是( C )。
A 运行速度快B 占用空间少C 时间复杂度低D 代码短7、以下不可以使用分治法求解的是( D )。
A 棋盘覆盖问题B 选择问题C 归并排序D 0/1背包问题8. 实现循环赛日程表利用的算法是( A )。
A、分治策略B、动态规划法C、贪心法D、回溯法9.下面不是分支界限法搜索方式的是( D )。
A、广度优先B、最小耗费优先C、最大效益优先D、深度优先10.下列算法中通常以深度优先方式系统搜索问题解的是( D )。
A、备忘录法B、动态规划法C、贪心法D、回溯法11.备忘录方法是那种算法的变形。
( B )A、分治法B、动态规划法C、贪心法D、回溯法12.哈夫曼编码的贪心算法所需的计算时间为( B )。
A、O(n2n)B、O(nlogn)C、O(2n)D、O(n)13.分支限界法解最大团问题时,活结点表的组织形式是( B )。
A、最小堆B、最大堆C、栈D、数组14.最长公共子序列算法利用的算法是( B )。
A、分支界限法B、动态规划法C、贪心法D、回溯法15.实现棋盘覆盖算法利用的算法是( A )。
A、分治法B、动态规划法C、贪心法D、回溯法16.下面是贪心算法的基本要素的是( C )。
A、重叠子问题B、构造最优解C、贪心选择性质D、定义最优解17.回溯法的效率不依赖于下列哪些因素( D )A.满足显约束的值的个数B. 计算约束函数的时间C.计算限界函数的时间D. 确定解空间的时间18.下面哪种函数是回溯法中为避免无效搜索采取的策略( B )A.递归函数 B.剪枝函数 C。
最小重量机器设计问题1。
问题描述设某一机器由n个部件组成,每一个部件都可以从m个不同的供应商处购得。
设wij是从供应商j处购得的部件i的重量,cij是相应的价格。
试设计一个算法,给出总价格不超过c的最小重量机器设计.算法设计:对于给定的机器部件重量和机器部件价格,计算总价格不超过d的最小重量机器设计。
2.算法流程分析设开始时bestx=[-1,—1,…,—1]则相应的排列树由x[0:n—1]的所有排列构成。
找最小重量机器设计的回溯算法Backtrack是类machine的公有成员。
私有数据成员整型数组Savex保存搜索过的路径,到达叶节点后将数据赋值给数组bestx。
成员bestw记录当前最小重量,cc表示当前花费,cw表示当前的重量。
在递归函数Backtrack中,在保证总花费不超过c的情况下:当i=n时,当前扩展结点是排列树的叶节点。
此时搜索到一个解,判断此时的最小重量是否小于当前最小重量,若小于则更新bestw, 并得到搜索路径bestx.当i〈n时,当前扩展结点位于排列树的第i—1层.当x[0:i]的花费小于给定最小花费时,算法进入排列树的第i层,否则将减去相应的子树。
算法用变量cc记录当前路径x[0:i]的费用。
3。
算法正确性证明通过几组实例证明合法的输入可以得到正确的输出.实例见附录第2部分。
4.算法复杂度分析时间复杂度是O(n2)5.参考文献[1] 王晓东编著,计算机算法设计与分析(第4版)。
北京:电子工业出版社,2012。
26。
附录(1)可执行代码如下:#include<iostream〉using namespace std;#define N 50class MinWmechine{int n; //部件个数int m;//供应商个数int COST; //题目中的Cint cw; //当前的重量int cc;//当前花费int bestw; //当前最小重量int bestx[N];int savex[N];int w[N][N];int c[N][N];public:MinWmechine();void machine_plan(int i);void prinout();};MinWmechine::MinWmechine(){cw=0; //当前的重量cc=0; //当前花费bestw=-1;//当前最小重量bestx[N];savex[N];cout<<”请输入部件个数:";cin〉〉n;cout〈〈”请输入供应商个数:"; cin>〉m;cout<<”请输入总价格不超过:"; cin>〉COST;for(int j=0;j<m;j++){for(int i=0;i〈n;i++)cout〈〈"请输入第"〈〈j+1〈<" 个供应商的第"〈〈i+1<〈”个部件的重量:”;cin>>w[i][j];cout〈〈”请输入第”〈<j+1〈<”个供应商的第”〈<i+1<<”个部件的价格:";cin〉>c[i][j];if(w[i][j]〈0 ||c[i][j]<0){cout〈<"重量或价钱不能为负数!\n";i=i—1;}}}}void MinWmechine::machine_plan(int i){if(i>=n){if(cw 〈bestw || bestw==—1){bestw=cw;for(int j=0;j〈n; j++) //把当前搜过的路径记下来savex[j]=bestx[j];return;}for(int j=0; j<m; j++)//依次递归尝试每个供应商{if(cc+c[i][j]〈COST){cc+=c[i][j];cw+=w[i][j];bestx[i]=j;machine_plan(i+1);bestx[i]=-1;cc-=c[i][j];cw—=w[i][j];}}}void MinWmechine::prinout(){int i,j,ccc=0;for(j=0;j〈m;j++){for(i=0;i〈n;i++){cout<〈"第”<<j+1〈<”供应商的第”<〈i+1〈〈”部件重量:”<〈w[i][j]〈〈" 价格:"<〈c[i][j]<<"\n”;}}for(j=0; j<n; j++){bestx[j]=-1;}machine_plan(0);cout<<”\n最小重量机器的重量是:"〈<bestw〈〈endl;for(int k=0;k〈n;k++){cout<<" 第"〈〈k+1〈〈" 部件来自供应商”〈<savex[k]+1<〈"\n”;ccc+=c[k][savex[k]];}cout〈〈"\n该机器的总价钱是: "<〈ccc<<endl;cout〈<endl;}int main(void){MinWmechine Y;Y。
习题2-1 求下列函数的渐进表达式:3n^2+10n; n^2/10+2n; 21+1/n; logn^3; 10 log3^n 。
解答:3n^2+10n=O(n^2),n^2/10+2^n=O(2^n),21+1/n=O(1),logn^3=O(logn),10log3^n=O(n).习题2-3 照渐进阶从低到高的顺序排列以下表达式:n!,4n^2,logn,3^n,20n,2,n^2/3。
解答:照渐进阶从高到低的顺序为:n!、3^n、4n^2 、20n、n^2/3、logn、2习题2-4(1)假设某算法在输入规模为n时的计算时间为T(n)=3*2^n。
在某台计算机上实现并完成该算法的时间为t秒。
现有另外一台计算机,其运行速度为第一台计算机的64倍,那么在这台新机器上用同一算法在t秒内能解输入规模为多大的问题?(2)若上述算法的计算时间改进为T(n)=n^2,其余条件不变,则在新机器上用t秒时间能解输入规模多大的问题?(3)若上述算法的计算时间进一步改进为,其余条件不变,那么在新机器上用t秒时间能解输入规模多大的问题?解答:(1)设能解输入规模为n1的问题,则t=3*2^n=3*2^n/64,解得n1=n+6(2)n1^2=64n^2得到n1=8n(3)由于T(n)=常数,因此算法可解任意规模的问题。
习题2-5 XYZ公司宣称他们最新研制的微处理器运行速度为其竞争对手ABC公司同类产品的100倍。
对于计算复杂性分别为n,n^2,n^3和n!的各算法,若用ABC公司的计算机能在1小时内能解输入规模为n的问题,那么用XYZ公司的计算机在1小时内分别能解输入规模为多大的问题?解答:n'=100nn'^2=100n^2得到n'=10nn'^3=100n^3得到n'=4.64nn'!=100n!得到n'<n+log100=n+6.64习题2-6对于下列各组函数f(n)和g(n),确定f(n)=O(g(n))或f(n)=Ω(g(n))或f(n)=θ(g(n)),并简述理由。
计算机算法设计与分析习题及答案一.选择题1、二分搜索算法是利用 A 实现的算法;A、分治策略B、动态规划法C、贪心法D、回溯法2、下列不是动态规划算法基本步骤的是 A ;A、找出最优解的性质B、构造最优解C、算出最优解D、定义最优解3、最大效益优先是A 的一搜索方式;A、分支界限法B、动态规划法C、贪心法D、回溯法4. 回溯法解旅行售货员问题时的解空间树是 A ;A、子集树B、排列树C、深度优先生成树D、广度优先生成树5.下列算法中通常以自底向上的方式求解最优解的是B ;A、备忘录法B、动态规划法C、贪心法D、回溯法6、衡量一个算法好坏的标准是 C ;A 运行速度快B 占用空间少C 时间复杂度低D 代码短7、以下不可以使用分治法求解的是 D ;A 棋盘覆盖问题B 选择问题C 归并排序D 0/1背包问题8. 实现循环赛日程表利用的算法是A ;A、分治策略B、动态规划法C、贪心法D、回溯法9.下面不是分支界限法搜索方式的是D ;A、广度优先B、最小耗费优先C、最大效益优先D、深度优先10.下列算法中通常以深度优先方式系统搜索问题解的是D ;A、备忘录法B、动态规划法C、贪心法D、回溯法11.备忘录方法是那种算法的变形; BA、分治法B、动态规划法C、贪心法D、回溯法12.哈夫曼编码的贪心算法所需的计算时间为B ;A、On2nB、OnlognC、O2nD、On13.分支限界法解最大团问题时,活结点表的组织形式是B ;A、最小堆B、最大堆C、栈D、数组14.最长公共子序列算法利用的算法是B;A、分支界限法B、动态规划法C、贪心法D、回溯法15.实现棋盘覆盖算法利用的算法是A ;A、分治法B、动态规划法C、贪心法D、回溯法16.下面是贪心算法的基本要素的是C ;A、重叠子问题B、构造最优解C、贪心选择性质D、定义最优解17.回溯法的效率不依赖于下列哪些因素 DA.满足显约束的值的个数B. 计算约束函数的时间C.计算限界函数的时间D. 确定解空间的时间18.下面哪种函数是回溯法中为避免无效搜索采取的策略BA.递归函数 B.剪枝函数 C;随机数函数 D.搜索函数19. D是贪心算法与动态规划算法的共同点;A、重叠子问题B、构造最优解C、贪心选择性质D、最优子结构性质20. 矩阵连乘问题的算法可由 B 设计实现;A、分支界限算法B、动态规划算法C、贪心算法D、回溯算法21. 分支限界法解旅行售货员问题时,活结点表的组织形式是 A ;A、最小堆B、最大堆C、栈D、数组22、Strassen矩阵乘法是利用A 实现的算法;A、分治策略B、动态规划法C、贪心法D、回溯法23、使用分治法求解不需要满足的条件是 A ;A 子问题必须是一样的B 子问题不能够重复C 子问题的解可以合并D 原问题和子问题使用相同的方法解24、下面问题 B 不能使用贪心法解决;A 单源最短路径问题B N皇后问题C 最小生成树问题D 背包问题25、下列算法中不能解决0/1背包问题的是 AA 贪心法B 动态规划C 回溯法D 分支限界法26、回溯法搜索状态空间树是按照 C 的顺序;A 中序遍历B 广度优先遍历C 深度优先遍历D 层次优先遍历27.实现合并排序利用的算法是A ;A、分治策略B、动态规划法C、贪心法D、回溯法28.下列是动态规划算法基本要素的是D ;A、定义最优解B、构造最优解C、算出最优解D、子问题重叠性质29.下列算法中通常以自底向下的方式求解最优解的是 B ;A、分治法B、动态规划法C、贪心法D、回溯法30.采用广度优先策略搜索的算法是A ;A、分支界限法B、动态规划法C、贪心法D、回溯法31、合并排序算法是利用 A 实现的算法;A、分治策略B、动态规划法C、贪心法D、回溯法32、背包问题的贪心算法所需的计算时间为 BA、On2nB、OnlognC、O2nD、On33.实现大整数的乘法是利用的算法C ;A、贪心法B、动态规划法C、分治策略D、回溯法34.0-1背包问题的回溯算法所需的计算时间为AA、On2nB、OnlognC、O2nD、On35.采用最大效益优先搜索方式的算法是A;A、分支界限法B、动态规划法C、贪心法D、回溯法36.贪心算法与动态规划算法的主要区别是B;A、最优子结构B、贪心选择性质C、构造最优解D、定义最优解37. 实现最大子段和利用的算法是B ;A、分治策略B、动态规划法C、贪心法D、回溯法38.优先队列式分支限界法选取扩展结点的原则是 C ;A、先进先出B、后进先出C、结点的优先级D、随机39.背包问题的贪心算法所需的计算时间为 B ;A、On2nB、OnlognC、O2nD、On40、广度优先是A 的一搜索方式;A、分支界限法B、动态规划法C、贪心法D、回溯法41. 一个问题可用动态规划算法或贪心算法求解的关键特征是问题的 B ;A、重叠子问题B、最优子结构性质C、贪心选择性质D、定义最优解42.采用贪心算法的最优装载问题的主要计算量在于将集装箱依其重量从小到大排序,故算法的时间复杂度为 B ;A 、On2nB 、OnlognC 、O2nD 、On43. 以深度优先方式系统搜索问题解的算法称为 D ;A 、分支界限算法B 、概率算法C 、贪心算法D 、回溯算法44. 实现最长公共子序列利用的算法是B ;A 、分治策略B 、动态规划法C 、贪心法D 、回溯法45. Hanoi 塔问题如下图所示;现要求将塔座A 上的的所有圆盘移到塔座B 上,并仍按同样顺序叠置;移动圆盘时遵守Hanoi 塔问题的移动规则;由此设计出解Hanoi 塔问题的递归算法正确的为:B46. 动态规划算法的基本要素为 CA. 最优子结构性质与贪心选择性质 B .重叠子问题性质与贪心选择性质C .最优子结构性质与重叠子问题性质 D. 预排序与递归调用 47. 能采用贪心算法求最优解的问题,一般具有的重要性质为: AA. 最优子结构性质与贪心选择性质 B .重叠子问题性质与贪心选择性质C .最优子结构性质与重叠子问题性质 D. 预排序与递归调用48. 回溯法在问题的解空间树中,按 D 策略,从根结点出发搜索解空间树;A.广度优先B. 活结点优先C.扩展结点优先D. 深度优先49. 分支限界法在问题的解空间树中,按 A 策略,从根结点出发搜索解空间树;A.广度优先B. 活结点优先C.扩展结点优先D. 深度优先50. 程序块 A 是回溯法中遍历排列树的算法框架程序;A.B. C. D. 51. 常见的两种分支限界法为DA. 广度优先分支限界法与深度优先分支限界法;B. 队列式FIFO 分支限界法与堆栈式分支限界法;C. 排列树法与子集树法;D. 队列式FIFO 分支限界法与优先队列式分支限界法;1.算法的复杂性有 时间 复杂性和 空间 ;2、程序是 算法用某种程序设计语言的具体实现;3、算法的“确定性”指的是组成算法的每条 指令 是清晰的,无歧义的;4. 矩阵连乘问题的算法可由 动态规划 设计实现;5、算法是指解决问题的 一种方法 或 一个过程 ;6、从分治法的一般设计模式可以看出,用它设计出的程序一般是 递归算法 ;7、问题的 最优子结构性质 是该问题可用动态规划算法或贪心算法求解的关键特征;8、以深度优先方式系统搜索问题解的算法称为 回溯法 ;9、计算一个算法时间复杂度通常可以计算 循环次数 、 基本操作的频率 或计算步; Hanoi 塔A. void hanoiint n, int A, int C, int B{ if n > 0{ hanoin-1,A,C, B;moven,a,b; hanoin-1, C, B, A; }} B. void hanoiint n, int A, int B, int C { if n > 0 { hanoin-1, A, C, B; moven,a,b; hanoin-1, C, B, A; } }C. void hanoiint n, int C, int B, int A { if n > 0 { hanoin-1, A, C, B; moven,a,b; hanoin-1, C, B, A; } }D. void hanoiint n, int C, int A, int B { if n > 0 { hanoin-1, A, C, B; moven,a,b; hanoin-1, C, B, A; } } void backtrack int t{ if t>n outputx; else for int i=t;i<=n;i++ { swapxt, xi; if legalt backtrackt+1; swapxt, xi; } } void backtrack int t { if t>n outputx;elsefor int i=0;i<=1;i++ { xt=i; if legalt backtrackt+1; } }void backtrack int t { if t>n outputx; else for int i=0;i<=1;i++ { xt=i; if legalt backtrackt-1; } }voidbacktrack int t{ if t>n outputx; else for int i=t;i<=n;i++ { swapxt, xi; if legalt backtrackt+1;}}10、解决0/1背包问题可以使用动态规划、回溯法和分支限界法,其中不需要排序的是动态规划 ,需要排序的是回溯法 ,分支限界法 ;11、使用回溯法进行状态空间树裁剪分支时一般有两个标准:约束条件和目标函数的界,N皇后问题和0/1背包问题正好是两种不同的类型,其中同时使用约束条件和目标函数的界进行裁剪的是 0/1背包问题 ,只使用约束条件进行裁剪的是 N皇后问题 ;12、贪心选择性质是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别;13、矩阵连乘问题的算法可由动态规划设计实现;14.贪心算法的基本要素是贪心选择性质和最优子结构性质 ;15. 动态规划算法的基本思想是将待求解问题分解成若干子问题 ,先求解子问题 ,然后从这些子问题的解得到原问题的解;16.算法是由若干条指令组成的有穷序列,且要满足输入、输出、确定性和有限性四条性质;17、大整数乘积算法是用分治法来设计的;18、以广度优先或以最小耗费方式搜索问题解的算法称为分支限界法 ;19、贪心选择性质是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别;20.快速排序算法是基于分治策略的一种排序算法;21.动态规划算法的两个基本要素是. 最优子结构性质和重叠子问题性质 ;22.回溯法是一种既带有系统性又带有跳跃性的搜索算法;23.分支限界法主要有队列式FIFO 分支限界法和优先队列式分支限界法;24.分支限界法是一种既带有系统性又带有跳跃性的搜索算法;25.回溯法搜索解空间树时,常用的两种剪枝函数为约束函数和限界函数 ;26.任何可用计算机求解的问题所需的时间都与其规模有关;27.快速排序算法的性能取决于划分的对称性 ;28.所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到 ;29.所谓最优子结构性质是指问题的最优解包含了其子问题的最优解 ;30.回溯法是指具有限界函数的深度优先生成法 ;31.用回溯法解题的一个显着特征是在搜索过程中动态产生问题的解空间;在任何时刻,算法只保存从根结点到当前扩展结点的路径;如果解空间树中从根结点到叶结点的最长路径的长度为hn,则回溯法所需的计算空间通常为 Ohn ;32.回溯法的算法框架按照问题的解空间一般分为子集树算法框架与排列树算法框架;33.用回溯法解0/1背包问题时,该问题的解空间结构为子集树结构;34.用回溯法解批处理作业调度问题时,该问题的解空间结构为排列树结构;35.旅行售货员问题的解空间树是排列树 ;三、算法填空1.背包问题的贪心算法void Knapsackint n,float M,float v,float w,float x{//重量为w1..n,价值为v1..n的 n个物品,装入容量为M的背包//用贪心算法求最优解向量x1..nint i; Sortn,v,w;for i=1;i<=n;i++ xi=0;float c=M;for i=1;i<=n;i++{if wi>c break;xi=1;c-=wi;}if i<=n xi=c/wi;}2.最大子段和: 动态规划算法int MaxSumint n, int a{int sum=0, b=0; //sum存储当前最大的bj, b存储bjfor int j=1; j<=n; j++{ if b>0 b+= aj ;else b=ai; ; //一旦某个区段和为负,则从下一个位置累和 ifb>sum sum=b;}return sum;}3.贪心算法求活动安排问题template<class Type>void GreedySelector int n, Type s, Type f, bool A{A1=true;int j=1;for int i=2;i<=n;i++if si>=fj{ Ai=true;j=i;}else Ai=false;}4.快速排序template<class Type>void QuickSort Type a, int p, int r{if p<r{int q=Partitiona,p,r;QuickSort a,p,q-1; //对左半段排序QuickSort a,q+1,r; //对右半段排序}}5. 回溯法解迷宫问题迷宫用二维数组存储,用'H'表示墙,'O'表示通道int x1,y1,success=0; //出口点void MazePathint x,int y{//递归求解:求迷宫maze从入口x,y到出口x1,y1的一条路径mazexy=''; //路径置为if x==x1&&y==y1 success=1; //到出口则成功else{if mazexy+1=='O' MazePathx,++y;//东邻方格是通路,向东尝试if success&&mazex+1y=='O' MazePath++x,y;//不成功且南邻方格是通路,向南尝试if success&&mazexy-1=='O' MazePathx,--y;//不成功且西邻方格是通路,向西尝试if success&&mazex-1y=='O' MazePath--x,y;//不成功且北邻方格是通路,向北尝试}if success mazexy=''; //死胡同置为}四、算法设计题1. 给定已按升序排好序的n个元素a0:n-1,现要在这n个元素中找出一特定元素x,返回其在数组中的位置,如果未找到返回-1;写出二分搜索的算法,并分析其时间复杂度;template<class Type>int BinarySearchType a, const Type& x, int n{//在a0:n中搜索x,找到x时返回其在数组中的位置,否则返回-1Int left=0; int right=n-1;While left<=right{int middle=left+right/2;if x==amiddle return middle;if x>amiddle left=middle+1;else right=middle-1;}Return -1;}时间复杂性为Ologn2. 利用分治算法写出合并排序的算法,并分析其时间复杂度void MergeSortType a, int left, int right{if left<right {//至少有2个元素int i=left+right/2; //取中点mergeSorta, left, i;mergeSorta, i+1, right;mergea, b, left, i, right; //合并到数组bcopya, b, left, right; //复制回数组a}}算法在最坏情况下的时间复杂度为Onlogn;3.N皇后回溯法bool Queen::Placeint k{ //检查xk位置是否合法for int j=1;j<k;j++if absk-j==absxj-xk||xj==xk return false;return true;}void Queen::Backtrackint t{if t>n sum++;else for int i=1;i<=n;i++{xt=i;if 约束函数 Backtrackt+1;}}4.最大团问题void Clique::Backtrackint i // 计算最大团{ if i > n { // 到达叶结点for int j = 1; j <= n; j++ bestxj = xj;bestn = cn; return;}// 检查顶点 i 与当前团的连接int OK = 1;for int j = 1; j < i; j++if xj && aij == 0 // i与j不相连{OK = 0; break;}if OK { // 进入左子树xi = 1; cn++;Backtracki+1;xi = 0; cn--; }if cn+n-i>bestn { // 进入右子树xi = 0;Backtracki+1; }}5. 顺序表存储表示如下:typedef struct{RedType rMAXSIZE+1; //顺序表int length; //顺序表长度}SqList;编写对顺序表L进行快速排序的算法;int PartitionSqList &L,int low,int high //算法10.6b{//交换顺序表L中子表L.rlow..high的记录,枢轴记录到位,并返回其所在位置, //此时在它之前后的记录均不大小于它.int pivotkey;L.r0=L.rlow; //用子表的第一个记录作枢轴记录pivotkey=L.rlow.key; //枢轴记录关键字while low<high //从表的两端交替地向中间扫描{while low<high&&L.rhigh.key>=pivotkey --high;L.rlow=L.rhigh; //将比枢轴记录小的记录移到低端while low<high&&L.rlow.key<=pivotkey ++low;L.rhigh=L.rlow; //将比枢轴记录大的记录移到高端}L.rlow=L.r0; //枢轴记录到位return low; //返回枢轴位置}void QSortSqList &L,int low,int high{//对顺序表L中的子序列L.rlow..high作快速排序int pivotloc;if low<high //长度>1{pivotloc=PartitionL,low,high; //将L.rlow..high一分为二QSortL,low,pivotloc-1; //对低子表递归排序,pivotloc是枢轴位置 QSortL,pivotloc+1,high; //对高子表递归排序}}void QuickSortSqList &L{//对顺序表L作快速排序QSortL,1,L.length; }。
第一章作业1.证明下列Ο、Ω和Θ的性质1)f=Ο(g)当且仅当g=Ω(f)证明:充分性。
若f=Ο(g),则必然存在常数c1>0和n0,使得∀n≥n0,有f≤c1*g(n)。
由于c1≠0,故g(n) ≥ 1/ c1 *f(n),故g=Ω(f)。
必要性。
同理,若g=Ω(f),则必然存在c2>0和n0,使得∀n≥n0,有g(n) ≥ c2 *f(n).由于c2≠0,故f(n) ≤ 1/ c2*f(n),故f=Ο(g)。
2)若f=Θ(g)则g=Θ(f)证明:若f=Θ(g),则必然存在常数c1>0,c2>0和n0,使得∀n≥n0,有c1*g(n) ≤f(n) ≤ c2*g(n)。
由于c1≠0,c2≠0,f(n) ≥c1*g(n)可得g(n) ≤ 1/c1*f(n),同时,f(n) ≤c2*g(n),有g(n) ≥ 1/c2*f(n),即1/c2*f(n) ≤g(n) ≤ 1/c1*f(n),故g=Θ(f)。
3)Ο(f+g)= Ο(max(f,g)),对于Ω和Θ同样成立。
证明:设F(n)= Ο(f+g),则存在c1>0,和n1,使得∀n≥n1,有F(n) ≤ c1 (f(n)+g(n))= c1 f(n) + c1g(n)≤ c1*max{f,g}+ c1*max{f,g}=2 c1*max{f,g}所以,F(n)=Ο(max(f,g)),即Ο(f+g)= Ο(max(f,g))对于Ω和Θ同理证明可以成立。
4)log(n!)= Θ(nlogn)证明:∙由于log(n!)=∑=n i i 1log ≤∑=ni n 1log =nlogn ,所以可得log(n!)= Ο(nlogn)。
∙由于对所有的偶数n 有,log(n!)= ∑=n i i 1log ≥∑=n n i i 2/log ≥∑=nn i n 2/2/log ≥(n/2)log(n/2)=(nlogn)/2-n/2。
当n ≥4,(nlogn)/2-n/2≥(nlogn)/4,故可得∀n ≥4,log(n!) ≥(nlogn)/4,即log(n!)= Ω(nlogn)。
综合以上两点可得log(n!)= Θ(nlogn)2. 设计一个算法,求给定n 个元素的第二大元素,并给出算法在最坏情况下使用的比较次数。
(复杂度至多为2n-3)算法:V oid findsecond(ElemType A[]){for (i=2; i<=n;i++)if (A[1]<A[i]){temp=A[1];A[1]=A[i];A[i]=temp;}for (i=3; i<=n;i++)if (A[2]<A[i]){temp=A[1];A[1]=A[i];A[i]=temp;}return A[2];}该算法使用的比较次数为:2n-33.设计一个算法,求给定n个元素的最大和最小元素。
(要求算法的复杂度至多为1.5n)算法:void Maxmin2(A;l,r;int x;int y);{if (l=r) { x=A[l]; y=A[r]; return;}if (r-l=1){ if (A[l]<A[r]) { x=A[l]; y=A[r];}else { x=A[r]; y=A[l];}return;}else { mid:=(l+r) div 2;Maxmin2(A,l,mid,x1,y1);Maxmin2(A,mid+1,r,x2,y2);x=min(x1,x2); y=max(y1,y2); }}该算法使用的比较次数为:1.5n-24.给定多项式p(x)=a n x n+ a n-1x n-1+…+a1x+a0,假设使用以下方法求解:p=a0;xpower=1;for (i=1; i<=n; i++){ xpower=x * xpower;p=p+a i * xpower;}求(1)该算法最坏情况下使用的加法和乘法分别为多少次?(2)能不能对算法的性能进行提高?解:(1)该算法最坏情况下使用的加法n次,乘法2n次(2)改进的算法为:float Horner(A, float x){p=A[n+1];for (j=1; j<=n; j++)p=x*p+A[n-j];return p;}该算法中使用加法n次,乘法n次第二章1.求解下列递推关系:1)当n≥1时,f(n)=3f(n-1);f(0)=5解:f(n)=3f(n-1)=32f(n-2)=…=3n f(n-n)= 3n *5=5*3n2) 当n≥2时,f(n)=5f(n-1)-6f(n-2);f(0)=1;f(1)=0解:该递推关系的特征方程为:x2-5x+6=0特征根为:r1=2;r2=3故f(n)=c1*2n+c2*3n有f(0)= c1*20+c2*30== c1+c2=1 且f(1)= c1*21+c2*31== 2c1+c32=0 可得c1 =3,c2=-2故f(n)=3*2n-2*3n3) 当n≥1时,f(n)=f(n-1)+n2;f(0)=0解:f(n)= f(n-1)+n2= f(n-2)+ (n-1)2+n2=….= f(0)+12+22+…+ (n-1)2+n2=12+22+…+ (n-1)2+n2=1/6 n(n+1)(2n+1)4) 当n≥1时,f(n)=2f(n-1)+n2;f(0)=1解:设f(n)=2n f’(n),且f’(0)= f(0)=1则2n f’(n)=2*(2n-1f’(n -1))+ n 2即f’(n)= f’(n -1)+n n 22 = f’(0)+∑=n i i i 122 =1+∑=n i ii 122所以f(n)= 2n *(1+∑=n i ii 122)=2n *(10-n n 26+)=10*2n -(n+6) 5) 当n ≥1时,f(n)=nf(n-1)+1; f(0)=1解:f(n)=n!*( f’(0)+ ∑=ni i 1!1) = n!*( 1+ ∑=ni i 1!1)2.求解下面的递推式:当n ≥2时,f(n)=4f(n/2)+n ; f(1)=1。
假设n 为2的幂,用直接展开法求解递推式。
解:令k n 2=f(n)=4f(n/2)+n=n n nf ++)2)2(4(*42 =n n nf ++2)2(422 =n n n nf +++22)2(4233 =….=n n n n f k k k++++-22)2(41 =n f k k )122()1(41++++-=n n k )12(2-+=n n -223.求解下面的递推式:当n ≥2时,f(n)=9f(n/3)+n 2; f(1)=1。
假设n 为3的幂,用直接展开法求解递推式。
解:令k n 3= f(n) =2)3(9n nf +=222))3()3(9(9n n n f ++=2222)3(9n n n f ++=22233)3(9n n n nf +++=….=2)3(9kn nf k k +=n n n 322log +4. 法求解递推式的上界:当n ≥4时,n n f n f n f +⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢=)43()4()(;当n<4时,f(n)=4。
解: 由于递推式为44)43()4(4)(≥<⎪⎩⎪⎨⎧+⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢=n n n n f n f n f 这里14341=+ 故作猜想n nf n f +=)2(2)(的解为:n n n n f 4log )(+=故对原递推式做猜想n n cn n f 4log )(+≤ 由于n n f n f n f +⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢=)43()4()(n n n n c n n n c +⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢⎥⎦⎥⎢⎣⎢≤43443log 43444log 4n nn n c n n n c ++++≤43443log 43444log 4=n n cn n cn 5)43log (log 43)4log (log 41+++-n cn n cn 5)3log 432(log +--=若使f(n)满足上界为n n cn 4log +则必有n n cn n cn n cn 4log 5)3log 432(log +≤+-- 即0)3log 432(≤+--n cn 所以23.13log 4321=-≥c故n n n n f 4log 23.1)(+≤,即上界为n n n 4log 23.1+4. 设计算法,求解问题:有一楼梯共M 级,刚开始时你再第一级,若每次只能跨上一级或二级,要走上第M 级,共有多少种走法?int fa(int m){int z;if (m==1) z=1;else if (m==2) z=2;、else z=fa(n-1)+fa(n-2);return z;}5.设计算法,一个射击运动员打靶,靶一共有10环,连开10枪打中90环的可能性有多少种?这道题的思路与字符串的组合很像,用递归解决。
一次射击有11种可能,命中1环至10环,或脱靶。
函数功能:求解number次打中sum环的种数函数参数: number为打靶次数,sum为需要命中的环数,result用来保存中间结果,total记录种数void ShootProblem_Solution(int number, int sum, vector<int> &result, int &total){I if(sum < 0 || number * 10 < sum)//加number * 10 < sum非常重要,它可以减少大量的递归,类似剪枝操作return;if(number == 1) //最后一枪{if(sum <= 10) //如果剩余环数小于10,只要最后一枪打sum环就可以了{for(unsigned i = 0; i < result.size(); i++)cout<<result[i]<<' ';cout<<sum<<endl;total++;return;}elsereturn;}for(unsigned i = 0; i <= 10; i++) //命中0-10环{result.push_back(i);ShootProblem_Solution(number-1, sum-i, result, total); //针对剩余环数递归求解result.pop_back();}}void ShootProblem(int number, int sum){int total = 0;vector<int> result;ShootProblem_Solution(number, sum, result, total);cout<<"total nums = "<<total<<endl;}int main(){ShootProblem(10, 90);return 0;}6.设计算法,求解猴子吃桃问题:有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,依此类推),第九天正好吃完,问猴子们摘来了多少桃子?思路:可假设有第十天,则第十天剩余的桃子数目为0,由此递推可得每一天剩余的桃子数目。