算法设计与分析习题Word文档格式.docx

上传人:b****5 文档编号:17540682 上传时间:2022-12-07 格式:DOCX 页数:31 大小:752.31KB
下载 相关 举报
算法设计与分析习题Word文档格式.docx_第1页
第1页 / 共31页
算法设计与分析习题Word文档格式.docx_第2页
第2页 / 共31页
算法设计与分析习题Word文档格式.docx_第3页
第3页 / 共31页
算法设计与分析习题Word文档格式.docx_第4页
第4页 / 共31页
算法设计与分析习题Word文档格式.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

算法设计与分析习题Word文档格式.docx

《算法设计与分析习题Word文档格式.docx》由会员分享,可在线阅读,更多相关《算法设计与分析习题Word文档格式.docx(31页珍藏版)》请在冰豆网上搜索。

算法设计与分析习题Word文档格式.docx

  递归法:

汉诺塔问题?

兔子序列(上楼梯问题)?

  整数划分问题?

  蛮力法:

百鸡百钱问题?

倒推法:

穿越沙漠问题?

算法如下:

(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;

●整数划分问题

问题描述:

将正整数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<

m)returnq(n,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;

x=x+1) 

for(y=1;

=33;

y=y+1) 

z=100-x-y;

if(zmod3=0and

5*x+3*y+z/3=100) 

{print(thecocknumberis"

}

以上算法只需要枚举尝试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<

high)

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]<

a[j]){fmax=a[j];

fmin=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;

当n=2时,查找查找最大最小元只需要1次比较,T

(2)=1;

时间复杂度记为O

(1)。

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<

tr+s&

dc<

tc+s)//特殊方格在此棋盘中

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);

}//覆盖其余方格

//覆盖右上角子棋盘

dc>

=tc+s)//特殊方格在此棋盘中

chessBoard(tr,tc+s,dr,dc,s);

board[tr+s-1][tc+s]=t;

//用t号L型骨牌覆盖左下角

chessBoard(tr,tc+s,tr+s-1,tc+s,s);

//覆盖左下角子棋盘

if(dr>

=tr+s&

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);

//覆盖右下角子棋盘

=tc+s)//特殊方格在此棋盘中

chessBoard(tr+s,tc+s,dr,dc,s);

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<

m;

i++)C[i][0]=0;

//y序列空

n;

i++)C[0][i]=0;

//x序列空

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<

=n;

试设计一个算法,计算出游艇从出租站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<

w[n])   //i=n时,只有1个物品 

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<

n时,xi…xn多个物品

{if(M<

w[i])

m[i][M]=m[i+1][M];

elseif(M>

{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++)//判断前n-1个物体是否放入背包

{if(m[i][M]=m[i+1][M])x[i]=0;

{x[i]=1;

x[n]=(m[n][M]>

0)?

1:

0;

//判断第n个物体是否放入背包

O(n)  

第4章贪心算法

1、贪心算法基本思想?

从问题的初始解出发逐步逼近给定的目标,每一步都做出当前看来是最优的选择(贪心选择),最终得到整个问题的最优解

2、贪心算法的基本要素?

贪心选择性;

最优子结构

3、贪心算法与动态规划算法的异同?

1)相同点:

 对于要求解的问题都具有最优子结构;

2)不同点:

算法的基本思想不同;

  求解问题的类型不同;

    例:

普通背包问题  贪心算法求解

      0-1背包问题  动态规划算法求解

4、设计普通背包装载问题的贪心算法?

并分析其时间复杂度

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 教育学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1