算法设计与分析习题.docx
- 文档编号:4243341
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:29
- 大小:421.63KB
算法设计与分析习题.docx
《算法设计与分析习题.docx》由会员分享,可在线阅读,更多相关《算法设计与分析习题.docx(29页珍藏版)》请在冰豆网上搜索。
算法设计与分析习题
《算法设计与分析》习题
第一章算法引论
1、算法的定义?
答:
算法就是指在解决问题时,按照某种机械步骤一定可以得到问题结果的处理过程。
通俗讲,算法:
就就是解决问题的方法或过程。
2、算法的特征?
答:
1)算法有零个或多个输入;2)算法有一个或多个输出;3)确定性;4)有穷性
3、算法的描述方法有几种?
答:
自然语言、图形、伪代码、计算机程序设计语言
4、衡量算法的优劣从哪几个方面?
答:
(1)算法实现所耗费的时间(时间复杂度);
(2)算法实现所所耗费的存储空间(空间复杂度);
(3)算法应易于理解,易于编码,易于调试等等。
5、时间复杂度、空间复杂度定义?
答:
指的就是算法在运行过程中所需要的资源(时间、空间)多少。
6、时间复杂度计算:
{i=1;
while(i<=n)
i=i*2;}
答:
语句①执行次数1次,
语句②③执行次数f(n),2^f(n)<=n,则f(n)<=log2n;
算法执行时间:
T(n)=2log2n+1
时间复杂度:
记为O(log2n);
7、递归算法的特点?
答:
①每个递归函数都必须有非递归定义的初值;否则,递归函数无法计算;(递归终止条件)
②递归中用较小自变量函数值来表达较大自变量函数值;(递归方程式)
8、算法设计中常用的算法设计策略?
答:
①蛮力法;②倒推法;③循环与递归;④分治法;
⑤动态规划法;⑥贪心法;⑦回溯法;⑧分治限界法
9、设计算法:
递归法:
汉诺塔问题?
兔子序列(上楼梯问题)?
整数划分问题?
蛮力法:
百鸡百钱问题?
倒推法:
穿越沙漠问题?
答:
算法如下:
(1)递归法
●汉诺塔问题
voidhanoi(intn,inta,intb,intc)
{if(n>0)
{
hanoi(n-1,a,c,b);
move(a,b);
hanoi(n-1,c,b,a);
}}
●
兔子序列(fibonaci数列)
递归实现:
IntF(intn)
{
if(n<=2)return1;
else
returnF(n-1)+F(n-2);
}
●
上楼梯问题
IntF(intn)
{
if(n=1)return1
if(n=2)return2;
else
returnF(n-1)+F(n-2);
}
●整数划分问题
问题描述:
将正整数n表示成一系列正整数之与,n=n1+n1+n3+…
将最大加数不大于m的划分个数,记作q(n,m)。
正整数n的划分数p(n)=q(n,n)。
可以建立q(n,m)的如下递归关系:
递归算法:
Intq(intn,intm){
if(n<1||m<1)return0;
If((n=1)||(m=1))return1;
If(n If(n=m)returnq(n,m-1)+1; else returnq(n,m-1)+q(n-m,m); } (2)蛮力法: 百鸡百钱问题 算法设计1: 设x,y,z分别为公鸡、母鸡、小鸡的数量。 约束条件: x+y+z=100且5*x+3*y+z/3=100 main() {intx,y,z; for(x=1;x<=20;x=x+1) for(y=1;y<=34;y=y+1) for(z=1;z<=100;z=z+1) if(100=x+y+zand100=5*x+3*y+z/3) { print(thecocknumberis",x); print(thehennumberis",y); print(thechicknumberis"z);} } 算法分析: 以上算法需要枚举尝试20*34*100=68000次。 算法的效率显然太低 算法设计2: 在公鸡(x)、母鸡(y)的数量确定后,小鸡 的数量 z就固定为100-x-y,无需再进行枚举了。 此时约束条件只有一个: 5*x+3*y+z/3=100 main() { intx,y,z; for(x=1;x<=20;x=x+1) for(y=1;y<=33;y=y+1) { z=100-x-y; if(zmod3=0and 5*x+3*y+z/3=100) {print(thecocknumberis",x); print(thehennumberis",y); print(thechicknumberis"z);} } } 算法分析: 以上算法只需要枚举尝试20*33=660次。 实现时约束条件又限定Z能被3整除时,才会判断“5*x+3*y+z/3=100”。 这样省去了z不整除3时的算术计算与条件判断,进一步提高了算法的效率。 (3)倒推法: 穿越沙漠问题 desert() {intdis,k,oil,k;//dis表示距终点的距离,k表示贮油点从后到前的序号 dis=500;k=1;oil=500; //初始化 while(dis<1000) { print(“storepoint”,k,”distance”,1000-dis,”oilquantity”,oil)//1000-dis则表示距起点的距离, k=k+1;//k表示储油点从后到前的序号 dis=dis+500/(2*k-1); oil=500*k; } print(“storepoint”,k,”distance”,dis,”oilquantity”,oil); } 第二章分治算法 1、分治算法基本思想就是什么? 适合用分治算法解决的问题,一般具有几个特征? 分治算法基本步骤就是什么? 答: 1)基本思想: 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 2)特征: Ø该问题的规模缩小到一定的程度就可以容易解决; Ø该问题可以分解为若干个规模较小的相同子问题,即该问题具有最优子结构性质; Ø该问题所分解出的各个子问题就是相互独立的,即子问题之间不包含公共的子问题。 Ø4)利用该问题分解出子问题解可以合并为该问题解; 3)基本步骤: 分解、求小问题解、合并 2、改写二分查找算法: 设a[1…n]就是一个已经排好序的数组,改写二分查找算法: ✓当搜索元素x不在数组中时,返回小于x的最大元素位置i,与大于x的最小元素位置j;(即返回x的左、右2个元素) ✓当搜索元素x在数组中时,i与j相同,均为x在数组中的位置。 并计算其时间复杂度? 答: 3、设计一个合并排序的算法? (分治法解) 并计算其时间复杂度? (要求写出递推公式,及其求解过程) 答: voidMergeSort(intA[],intlow,inthigh) {intmiddle; if(low { middle=(low+high)/2;//取中点 MergeSort(A,low,middle); MergeSort(A,middle+1,high); Merge(A,low,middle,high); //合并算法 } } voidMerge(intA[],intlow,intmiddle,inthigh)//合并过程描述: { inti,j,k;int*B=newint[high-low+1]; i=low;j=middle+1;k=low; while(i<=middle&&j<=high){ //两个子序列非空 if(A[i]<=A[j]) B[k++]=A[i++]; else B[k++]=A[j++]; } while(i<=middle) B[k++]=A[i++]; //子序列A[low,middle]非空,将A复制到B while(j<=high) B[k++]=A[j++];/子序列A[middle+1,high]非空,将A复制到B for(i=low;i<=high;i++) A[i++]=B[i++]; //将合并后的序列复制回A } •合并排序算法运行时间T(n)的递归形式为: ◆分析该算法时间复杂度: 令T(n)为元素个数为n时所需比较次数(时间): 当n=1时, 时间复杂度记为O (1)。 当n>1时,T(n)=2T(n/2)+O(n) =2(2T(n/22)+O(n/2))+O(n) =22T(n/22)+2O(n) =23T(n/23)+3O(n) =…… =2xT(n/2x)+x*O(n) 分解到最后只有2个元素可以求解,n/2x=1,x=logn; 故T(n)=n*T (1)+n*logn,故时间复杂度记为: O(n*logn) 4、金块问题(求最大最小元问题) 老板有一袋金块(共n块),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。 假设有一台比较重量的仪器,我们希望用最少的比较次数找出最重的金块。 要求: 1)设计一算法求解该问题? (分治法解) 2)计算其时间复杂度? (要求写出递推公式,及其求解过程) 答: 递归求取最大与最小元素 maxmin(inti,intj,float&fmax,float&fmin) {intmid;floatlmax,lmin,rmax,rmin; if(i=j){fmax=a[i];fmin=a[i];}//只有1个元素 elseif(i=j-1)//只有2个元素 if(a[i] else{fmax=a[i];fmin=a[j];} else//多于2个元素 {mid=(i+j)/2; maxmin(i,mid,lmax,lmin);//递归调用算法求最大最小 maxmin(mid+1,j,rmax,rmin);//递归调用算法求最大最小 if(lmax>rmax)fmax=lmax;//合并取大 elsefmax=rmax; if(lmin>rmin)fmin=rmin;//合并取小 elsefmin=lmin; } ◆分析该算法时间复杂度: 令T(n)为元素个数为n时所需比较次数(时间): 当n=2时,查找查找最大最小元只需要1次比较,T (2)=1;时间复杂度记为O (1)。 当n>2时,T(n)=2T(n/2)+2T (2) =4T(n/4)+4T (2)+2T (2) =8T(n/8)+8+4+2 =…… =2xT(n/2x)+2x+2x-1+…+8+4+2 分解到最后只有2个元素可以求解,n/2x=2, T(n)=2x*1+2x+2x-1…+22+21 =2x*1+(2-2x*2)/(1-2) =2x+2x+1-2 =3n/2-2 故时间复杂度记为: O(n) 5、用分治思想设计一个有效的算法,可以进行两个n位大整数的乘法运算? 并计算其时间复杂度? (要求写出递推公式,及其求解过程) 答: intmult(intx,inty,intn)//x,y为两个n位整数 {s=sign(x)*sign(y);//s为x*y的符号 x=abs(x);y=abs(y);intmul; if(n=1){mul=s*x*y;returnmul;} else//计算XY=ac2n+((a-b)(d-c)+ac+bd)2n/2+bd {inta=x左边n/2位;//移位操作,把X分为2块 intb=x右边n/2位; intc=y左边n/2位;//移位操作,把Y分为2块 intd=y右边n/2位; intm1=mult(a,c,n/2);//a,c还不够小继续分为2块,直到最后1×1位 intm2=mult(a-b,d-c,n/2); intm3=mult(b,d,n/2); mul=s*(m1*2n+(m1+m2+m3)*2n/2+m3); returnmul; }} 6、设计一棋盘覆盖问题算法(分治法)? 并计算其时间复杂度? (要求写出递推公式,及其求解过程) 在一个2k×2k个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。 在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。 (该算法中可能用到的变量: tr: 棋盘中左上角方格所在行; tc: 棋盘中左上角方格所在列。 dr: 残缺方块所在行; dl: 残缺方块所在列。 size: 棋盘的行数或列数; 用二维数组board[][],模拟棋盘。 ) 答: voidchessBoard(inttr,inttc,intdr,intdc,intsize) { if(size==1)return;//size: 棋盘行数 intt=tile++,//L型骨牌号 s=size/2;//分割棋盘 //覆盖左上角子棋盘 if(dr chessBoard(tr,tc,dr,dc,s); else{//此棋盘中无特殊方格 board[tr+s-1][tc+s-1]=t;//用t号L型骨牌覆盖右下角 chessBoard(tr,tc,tr+s-1,tc+s-1,s);}//覆盖其余方格 //覆盖右上角子棋盘 if(dr chessBoard(tr,tc+s,dr,dc,s); else{//此棋盘中无特殊方格 board[tr+s-1][tc+s]=t;//用t号L型骨牌覆盖左下角 chessBoard(tr,tc+s,tr+s-1,tc+s,s);}//覆盖其余方格 //覆盖左下角子棋盘 if(dr>=tr+s&&dc chessBoard(tr+s,tc,dr,dc,s); else{ board[tr+s][tc+s-1]=t;//用t号L型骨牌覆盖右上角 chessBoard(tr+s,tc,tr+s,tc+s-1,s);}//覆盖其余方格 //覆盖右下角子棋盘 if(dr>=tr+s&&dc>=tc+s)//特殊方格在此棋盘中 chessBoard(tr+s,tc+s,dr,dc,s); else{ board[tr+s][tc+s]=t;//用t号L型骨牌覆盖左上角 chessBoard(tr+s,tc+s,tr+s,tc+s,s);}//覆盖其余方格 } 第三章动态规划算法 1、动态规划算法基本思想? 动态规划算法与分治算法异同点? 适合用动态规划算法求解问题的基本要素? 动态规划算法的基本步骤? 答: 1)基本思想: 将待求解问题分解成若干个子问题;由于子问题有重叠,动态规划算法能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算、 2)相同: 都就是将原问题分解成小问题,通过小问题求解得到原问题解。 不同: ✓用分治法求解时,分解的子问题就是互相独立的,且与原问题类型一致。 分治算法实现一般用递归; ✓动态规划方法经分解得到的子问题往往不就是互相独立的;动态规划算法实现一般用循环; 3)基本要素: 具有最优子结构;子问题具有重叠性 4)步骤: 1)分析最优解的性质,并刻划其结构特征。 2)递推地定义最优值。 3)以自底向上的方式计算出最优值、 4)根据计算最优值时得到的信息,构造问题的最优解、 2、序列X={X1,X2,…Xm}与Y={Y1,Y2…Yn}的最长公共子序列为Z={Z1,Z2,…Zk} 用动态规划的方法求序列X与Y的最长公共子序列长度? (要求按照动态规划写出动态规划求解问题的步骤分析①最优子结构②写出递归方程③算法描述) 注: C[m][n]记录序列X与Y的最长公共子序列的长度 答: ①最优子结构 设序列X={x1,x2,…xm}与 序列Y={y1,y2,…yn}的一个 最长公共子序列Z={z1,z2,…zk} Ⅰ、若xm=yn,则zk=xm=yn,且{z1,z2,…zk-1}就是序列Xm-1与 序列Yn-1的最长公共自序列; Ⅱ、若xm≠yn,且xm≠zk,则Z就是Xm-1与Y的最长公共子序列; Ⅲ、若xm≠yn,且yn≠zk,则Z就是X与Yn-1的最长公共子序列; 由此可见,2个序列的最长公共子序列包含了这2个序列的前缀(去掉一个元素)的最长公共子序列。 即,原问题最优解,包含子问题最优解; 因此,最长公共子序列问题具有最优子结构性质。 ②写出递归方程 ③循环实现,计算最优值C[i][j],算法描述 IntlcsLength(x[],y[],b[][]) {intm=x、length-1; n=y、length-1; for(inti=1;i for(inti=1;i for(inti=1;i<=m;i++)//x序列长为m for(intj=1;j<=n;j++) //y序列长为n if(x[i]==y[j]) {C[i][j]=C[i-1][j-1]+1;b[i][j]=1;} elseif(c[i-1][j]>=c[i][j-1]) {C[i][j]=C[i-1][j];b[i][j]=2;} else {C[i][j]=C[i][j-1];b[i][j]=3;} returnC[m][n]; } ◆时间复杂度分析: 该算法时间复杂度: O(m*n) ④构造最长公共子序列,算法描述: voidLCS(charX[i],Y[j],intb[][]) { if(i==0||j==0)return; if(b[i][j]==1) {LCS(X[i-1],Y[j-1],b); system、out、print(x[i]);} elseif(b[i][j]==2) LCS(X[i-1],Y[j],b); elseif(b[i][j]==3) LCS(X[i],Y[j-1],b); } ◆时间复杂度分析: 此算法每一次递归调用使得i或j减1,因此该算法时间复杂度为O(m+n) 3、长江游艇俱乐部在长江上设置了n个游艇出租站1,2…n、 游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。 游艇出租站i到游艇出租站j之间的租金为r(i,j),其中1<=i 试设计一个算法,计算出游艇从出租站1到出租站n所需最少租金? (见习题集第三章算法设计与计算题T2) 4、掌握动态规划方法求解0-1背包问题? 答: ①分析问题的最优解结构 设(y1,y2,…yn)所给0-1背包容量为M的解; 则,(y2,…yn)相应子问题背包容量为M-w1的解; (即原问题最优解,包含了子问题最优解) ②递归定义最优值 ③计算最优值m(i,j) voidknapsack(intv[],intw[],intM,intm[][]) {intn=v、length; if(M m[n][M]=0; elseif(M>=w[n]) {m[n][M]=v[n];M=M-w[n];} for(inti=n-1;i>=1;i--)//i {if(M m[i][M]=m[i+1][M]; elseif(M>=w[n]) {m[i][M]=math、max(m[i+1][M],m[i+1][M-w[i]+v[i]); M=M-w[i];} } } ◆该算法时间复杂度: O(c*n) c常数 ④构造最优解 voidtrackack(intm[][],intw[],intM,intx[]) {//x[i]标记i就是否放入背包 intn=w、length; for(inti=1;i {if(m[i][M]=m[i+1][M])x[i]=0; else {x[i]=1;M=M-w[i];} } x[n]=(m[n][M]>0)? 1: 0;//判断第n个物体就是否放入背包 } ◆该算法时间复杂度: O(n) 第4章贪心算法 1、贪心算法基本思想? 答: 从问题的初始解出发逐步逼近给定的目标,每一步都做出当前瞧来就是最优的选择(贪心选择),最终得到整个问题的最优解 2、贪心算法的基本要素? 答: 贪心选择性;最优子结构 3、贪心算法与动态规划算法的异同? 答: 1)相同点: 对于要求解的问题都具有最优子结构; 2)不同点: 算法的基本思想不同; 求解问题的类型不同; 例: 普通背包问题 贪心算法求解 0-1背包问题 动态规划算法求解 4、设计普通背包装载问题的贪心算法? 并分析其时间复杂度? 答: float 如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。 copyright@ 2008-2022 冰点文档网站版权所有 经营许可证编号:鄂ICP备2022015515号-1=tc+s)//特殊方格在此棋盘中