算法设计方案分析晓东.docx

上传人:b****7 文档编号:9503081 上传时间:2023-02-05 格式:DOCX 页数:18 大小:25.42KB
下载 相关 举报
算法设计方案分析晓东.docx_第1页
第1页 / 共18页
算法设计方案分析晓东.docx_第2页
第2页 / 共18页
算法设计方案分析晓东.docx_第3页
第3页 / 共18页
算法设计方案分析晓东.docx_第4页
第4页 / 共18页
算法设计方案分析晓东.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

算法设计方案分析晓东.docx

《算法设计方案分析晓东.docx》由会员分享,可在线阅读,更多相关《算法设计方案分析晓东.docx(18页珍藏版)》请在冰豆网上搜索。

算法设计方案分析晓东.docx

算法设计方案分析晓东

习题2-1 求下列函数的渐进表达式:

3n^2+10n。

 n^2/10+2n。

 21+1/n。

 logn^3。

 10log3^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'=100n

n'^2=100n^2得到n'=10n

n'^3=100n^3得到n'=4.64n

n'!

=100n!

得到n'

习题2-6对于下列各组函数f(n)和g(n),确定f(n)=O(g(n))或f(n)=Ω(g(n))或f(n)=θ(g(n)),并简述理由。

解答:

(1)f(n)=logn^2。

g(n)=logn+5.logn^2=θ(logn+5)

(2)f(n)=logn^2。

g(n)=根号n.logn^2=O(根号n)

(3)f(n)=n。

g(n)=(logn)^2.n=Ω((logn)^2)

(4)f(n)=nlogn+n。

g(n)=logn.nlogn+n=Ω(logn)

(5)f(n)=10。

g(n)=log10.10=θ(log10)

(6)f(n)=(logn)^2。

g(n)=logn.(logn)^2=Ω(logn)

(7)f(n)=2^n。

g(n)=100n^2.2^n=Ω(100n^2)

(8)f(n)=2^n。

g(n)=3^n.2^n=O(3^n)

习题2-7证明:

如果一个算法在平均情况下的计算时间复杂性为θ(f(n)),则该算法在最坏情况下所需的计算时间为Ω(f(n))。

证明:

Tavg(N)=IeDn∑P(I)T(N,I)

            ≤IeDn∑P(I)IeDnmaxT(N,I')

            =T(N,I*)IeDn∑P(I)

            =T(N,I*)=Tmax(N)

因此,Tmax(N)=Ω(Tavg(N))=Ω(θ(f(n)))=Ω(f(n))

习题2-8求解下列递归方程:

So=0。

Sn=2Sn-1+2^n-1.

解答:

 1应用零化子化为齐次方程,

 2解此齐次方程的特征方程,

 3由特征根构造一般解,

 4再由初始条件确定待定系数,得到解为:

Sn=(n-1)2^n+1

习题2-9求解下列递归方程

Ho=2。

H1=8。

Hn=4Hn-1-4Hn-2.

解:

Hn=2^(n+1)(n+1)

第三章递归与分治策略

习题3-1 下面的7个算法都是解决二分搜索问题的算法。

请判断这7个算法的正确性。

如果算法不正确,请说明产生错误的原因。

如果算法正确,请给出算法的正确性证明。

publicstaticintbinarySearch1(int[]a,intx,intn)

{

 intleft=0。

intright=n-1。

 while(left<=right){

  intmiddle=(left+right)/2。

  if(x==a[middle])returnmiddle。

  if(x>a[middle])left=middle。

  elseright=middle。

 return-1。

}

publicstaticintbinarySearch2(int[]a,intx,intn)

{

 intleft=0。

intright=n-1。

 while(left

  intmiddle=(left+right)/2。

  if(x

  elseleft=middle。

 }

 if(x==a[left])returnleft。

 elsereturn-1

}

publicstaticintbinarySearch3(int[]a,intx,intn)

{

 intleft=0。

intright=n-1。

 while(left+1!

=right){

  intmiddle=(left+right)/2。

  if(x>=a[middle])left=middle。

  elseright=middle。

  }

 if(x==a[left])returnleft。

 elsereturn-1。

}

publicstaticintbinarySearch4(int[]a,intx,intn)

{

 if(n>0&&x>=a[0]){

  intleft=0。

intright=n-1。

  while(left

   intmiddle=(left+right)/2。

   if(x

   elseleft=middle。

   }

  if(x==a[left])returnleft。

  }

 return-1。

}

publicstaticintbinarySearch5(int[]a,intx,intn)

{

 if(n>0&&x>=a[0]){

  intleft=0。

intright=n-1。

  while(left

   intmiddle=(left+right+1)/2。

   if(x

   elseleft=middle。

   }

  if(x==a[left])returnleft。

  }

 return-1。

}

publicstaticintbinarySearch6(int[]a,intx,intn)

{

 if(n>0&&x>=a[0]){

  intleft=0。

intright=n-1。

  while(left

   intmiddle=(left+right+1)/2。

   if(x

   elseleft=middle+1。

   }

  if(x==a[left])returnleft。

  }

 return-1。

}

publicstaticintbinarySearch7(int[]a,intx,intn)

{

 if(n>0&&x>=a[0]){

  intleft=0。

intright=n-1。

  while(left

   intmiddle=(left+right+1)/2。

   if(x

   elseleft=middle。

   }

  if(x==a[left])returnleft。

  }

 return-1。

}

分析与解答:

算法binarySearch1数组段左右游标left和right的调整不正确,导致陷入死循环。

算法binarySearch2数组段左右游标left和right的调整不正确,导致当x=a[n-1]时返回错误。

算法binarySearch3数组段左右游标left和right的调整不正确,导致当x=a[n-1]时返回错误。

算法binarySearch4数组段左右游标left和right的调整不正确,导致陷入死循环。

算法binarySearch5正确,且当数组中有重复元素时,返回满足条件的最右元素。

算法binarySearch6数组段左右游标left和right的调整不正确,导致当x=a[n-1]时返回错误。

算法binarySearch7数组段左右游标left和right的调整不正确,导致当x=a[n-1]时陷入死循环。

习题3-2 设a[0:

n-1]是已排好序的数组。

请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。

当搜索元素在数组中时,i和j相同,均为x在数组中的位置。

分析与解答:

改写二分搜索算法如下:

publicstaticbooleanbinarySearch(int[]a,intx,intleft,intright,int[]ind)

{

 intmiddle。

 while(left<=right){

  middle=(left+right)/2。

  if(x==a[middle]){ind[0]=ind[1]=middle。

returntrue。

}

  if(x>a[middle])left=middle+1。

  elseright=middle-1。

 }

 ind[0]=right。

ind[1]=left。

 returnfalse。

}

返回的ind[1]是小于x的最大元素位置,ind[0]是大于x的最小元素的位置。

习题3-3 设a[0:

n-1]是有n个元素的数组,是非负整数。

试设计一个算法讲子数组与换位。

要求算法在最坏情况下耗时为,且只用到的辅助空间。

分析与解答:

算法:

三次求反法

Algorithm exchange(a,k,n)。

Begin

Inverse(n,0,k-1)。

inverse(n,k,n-1);inverse(n,0,n-1)

End.

Algorithm inverse(a,i,j)。

 Begin

    h=[(j-i+1)/2]。

Fork=0toh-1do

  Begin x=a[i+k]。

a[i+k]=a[j-k]。

a[j-k]=xend。

end

习题3-4 如果在合并排序算法的分割步中,讲数组a[0。

n-1]划分为[根号2】个子数组,每个子数组中有个元素。

然后递归地对分割后的子数组进行排序,最后将所得到的个排好序的子数组合并成所要求的排好序的数组。

设计一个实现上述策略的合并排序算法,并分析算法的计算复杂性。

分析与解答:

实现上述策略的合并排序算法如下:

publicstaticvoidmergesort(int[]a,intleft,intright)

{

  if(left

  intj=(int)Math.sqrt(right–left+1)。

  if(j>1){

   for(inti=0。

i

i++)mergesort(a,left+i*j,left+(i+1)*j-1)。

   mergesort(a,left+i*j,right)。

  }

  mergeall(a,left,right)。

 }

}

其中,算法mergeall合并根号n个排好序的数组段。

在最坏情况下,算法mergeall需要O(nlogn)时间。

因此上述算法所需的计算时间T(n)满足:

T(n)=O

(1),n<=1

T(n)=根号n*T(根号n),n>1

T(n)=O(nlogn)

 

此递归式的解为:

习题3-5  设S1,S2...Sk是整数集合,其中每个集合中整数取值范围是,且,试设计一个算法,在时间内将分别排序。

分析与解答:

用桶排序或基数排序算法思想可以实现整数集合排序。

习题3-6 设X[0:

n-1]和Y[0:

n-1]为两个数组,每个数组中还有n个已排好序的数。

试设计一个时间的算法,找出X和Y的2n个数的中位数。

分析与解答:

(1) 算法设计思想

考虑稍一般的问题:

设X[i1:

j1]和y[i2。

j2]是X和Y的排序好的子数组,且长度相同,即j1-i1=j2-i2。

找出这两个数组中2(i1-j1+1)个数的中位数。

首先注意到,若X(i1)<=Y(j2),则中位数median满足X(i)<=median<=Y(j2)。

同理若X(i1)>=Y(j2),则Y(j2)<=median<=X(i1)。

设m1=(i1+j1)/2,m2=(i2+j2)/2 ,则m1+m2=i1+i2+(j1-i1)/2+(j2-i2)/2

由于j1-i1=j2-i2,故(j1-i1)/2+(j2-i2)/2=j2-i2。

因此m1+m2=i1+j2。

当X(m1)=Y(m2)时,median=X(m1)=Y(m2)。

当X(m1)>Y(m2)时,设median1是X(m1:

j1)和Y(j2:

m2)的中位数,则median=median1。

当X(m1)

m1)和Y(m2:

j2)的中位数,类似地有median=median2。

通过以上讨论,可以设计出找出两个子数组X(i1:

j1)和Y(i2:

j2)的中位数median的算法。

(2) 设在最坏情况下,算法所需的计算时间为T(2n)。

由算法中m1和m2的选取策略可知,在递归调用时,数组X和Y的大小都减少了一半。

因此,T(2n)满足递归式:

 T(2n)=

(1),n<=1

T(2n)=T(n)+O

(1),n>=c

解此递归方程可得:

T(2n)=O(logn)。

习题3-7   Gray码是一个长度为2^n的序列。

序列中无相同元素,每个元素都是长度为n位的(0,1)串,相邻元素恰好只有1位不同。

用分治策略设计一个算法,对任意的n构造相应的Gray码。

分析与解答:

考察的简单情形。

n=1

0 1  

n=2

00 01  

11 10  

n=3

000 001 011 010

110 111 101 100

设n位Gray码序列为G(n)以相反顺序排列的序列为G^-1(n)。

从上面的简单情形可以看出G(n)的构造规律:

G(n+1)=OG(n)1G^-1(n)。

注意到G(n)的最后一个n位串与G^-1(n)的第1个n位串相同,可用数学归纳法证明G(n)的上述构造规律。

由此规律容易设计构造G(n)的分治法如下。

publicstaticvoidGray(intn)

{

 if(n==1){a[1]=0。

a[2]=1。

return。

}

 Gray(n-1)。

 for(intk=1<<(n-1),i=k。

i>0。

i--)a[2*k-i+1]=a[i]+k。

}

上述算法中将n位(0,1)串看做是二进制整数,第i个串存储在中。

完成计算之后,由out输出Gray码序列。

publicstaticvoidout(intn)

{

 intm=1<

 for(inti=1。

i<=m。

i++){

  Stringstr=Integer.toBinaryString(a[i])。

  ints=str.length()。

  for(intj=0。

j

j++)System.out.print(“0”)。

  System.out.println(Integer.toBinaryString(a[i])+””)。

 }

 System.out.println()。

}

第四章动态规划

习题4-1 设计一个时间的算法,找出由n个数组成的序列的最长单调递增子序列。

分析与解答:

引入一个数组b,使b[i]为已扫描部分的长度为i的升序子序列的最小终值。

按此思想设计的动态规划算法描述如下:

j:

=0。

 b[0]:

=-maxint。

 

         FOR i:

=1 TO n DO 

             IF a[i]>b[j] THEN 

                 BEGIN j:

=j+1。

b[j]:

=a[i]。

 END 

             ELSE

                 BEGIN    k:

=1。

                            while a[i]>b[k] DO k:

=k+1。

 

                            b[k]:

=a[i]。

 

                   END。

 

习题4-2考虑下面的整数线性规划问题:

  为非负整数,

试设计一个解此问题的动态规划算法,并分析算法的计算复杂性。

分析与解答:

该问题是一般情况下的背包问题,具有最优子结构性质。

设所给背包问题的子问题:

max∑CkXk(1..i)∑AkXk<=j

 

的最优值为m(i,j),即m(i,j)是背包容量为j,可选择物品为1,2,…,i时背包问题的最优值。

由背包问题的最优子结构性质,可以建立计算m(i,j)的递归式如下:

m(i,j)=max{m(i-1,j),m(i,j-ai)+ci}j>=ai,

m(i,j)=m(i-1,j),0<=j,ai

m(0,j)=m(i,0)。

m(i,j)=-*,j<0

 

按此递归式计算出的m(n,b)为最优值。

算法所需的计算时间为O(nb)。

习题4-3  给定一个由n行数字组成的数字三角形如图3-2所示。

试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大。

分析与解答:

记f(uij)为至ij元素的最大路径值,aij:

元素(i,j)之值。

递归式:

F(uij)=max{f(ui-1,j)+aij,f(ui-1,j+1)+aij}  (i=1,…n,  j=1,…i)

经过一次顺推,便可求出从顶至底n个数的n条路径(这n条路径为至底上n个数的n个最大总和的路径),求出这n个总和的最大值,即为正确答案。

数据结构:

 a[i,j].val:

 三角形上的数字,

 a[i,j].f:

    由(1,1)至该点的最大总和路径的总和值。

typenode=record

   val,f:

integer。

  end。

vara:

array[1..maxn,1..maxn]ofnode。

procedurefindmax。

begin

 a[1,1].f:

=a[1,1].val。

  fori:

=2tondo

  forj:

=1toido

   begin

    a[i,j].f:

=-1。

if(j<>1)and(a[i-1,j-1].f+a[i,j].val>a[i,j].f)

   thena[i,j].f:

=a[i-1,j-1].f+a[i,j].val。

   if(j<>i)and(a[i-1,j].f+a[i,j].val>a[i,j].f)

    thena[i,j].f:

=a[i-1,j].f+a[i,j].val

end。

 max:

=1。

 fori:

=2tondo

   ifa[n,i].f>a[n,max].fthen

        max:

=i。

  writeln(a[n,max].f)

end。

第五章贪心算法

习题5-1特殊的0-1背包问题

若在0-1背包问题中,各物品依重量递增排列时,其价值恰好依递减序排列。

对这个特殊的0-1背包问题,设计一个有效算法找出最优解,并说明算法的正确性。

分析与解答:

设所给的输入为W>0,wi>1,vi>0,1≤i≤n。

不妨设0≤w1≤w2≤..≤wn。

由题意知v1≥v2≥..≥vn>0。

由此可知vi/wi≥vi+1/wi+1,1≤i≤n-1.

贪心选择性质:

当w1>W时问题无解。

当w1≤W时,存在0-1背包问题的一个最优解S包含{1,2,..,n}使得1∈S。

事实上,设S包含{1,2,..,n}使0-1背包问题的一个最优解,且1不∈S。

对任意i∈S,取Si=S∪{1}-{i},则Si满足贪心选择性质的最优解。

习题5-2Fibonacci序列的Huffman编码

试证明:

若n个字符的频率恰好是前n个Fibonacci数,用贪心法得到它们的Huffman编码树一定为一棵“偏斜树”。

证明:

n个字符的频率恰好是前n个Fibonacci数,则相应的哈夫曼编码树自底向上第i个内结点中的数为k=0∑if(k)。

用数学归纳法容易证明k=0∑ifk

 因f1=1,f2=1,f3=2,可知i=1时,上述结论成立。

 设对i+2上述结论成立,即有k=0∑ifk

 fi+3=fi+2+fi+1>k=1∑ifk+fi+1=k=1∑i+1fk,

 说明对i+3上述结论成立.

该性质保证了频率恰好是前n个Fibonacci数的哈夫曼编码树具有“偏斜树”形状。

习题5-3 记T为图G=(V,E)的最小生成树,同时设顶点集合A包含V,设(u,v)∈E为连接A和V–A的权重最小的边,证明:

必有(u,v)∈T.

证明:

用反证法。

因为T为图G=(V,E)的最小生成树,在连接A和V–A的边中至少有一条属于T中。

假设(u,v)不属于T,则必有(u’,v’)

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

当前位置:首页 > 党团工作 > 入党转正申请

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

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