算法设计与分析基础习题参考答案

算法设计与分析基础习题参考答案
算法设计与分析基础习题参考答案

习题1.1

5..证明等式gcd(m,n)=gcd(n,m mod n)对每一对正整数m,n都成立.

Hint:

根据除法的定义不难证明:

如果d整除u和v, 那么d一定能整除u±v;

如果d整除u,那么d也能够整除u的任何整数倍ku.

对于任意一对正整数m,n,若d能整除m和n,那么d一定能整除n和r=m mod n=m-qn;显然,若d 能整除n和r,也一定能整除m=r+qn和n。

数对(m,n)和(n,r)具有相同的公约数的有限非空集,其中也包括了最大公约数。故gcd(m,n)=gcd(n,r)

6.对于第一个数小于第二个数的一对数字,欧几里得算法将会如何处理?该算法在处理这种输入的过程中,上述情况最多会发生几次?

Hint:

对于任何形如0<=m

gcd(m,n)=gcd(n,m)

并且这种交换处理只发生一次.

7.a.对于所有1≤m,n≤10的输入, Euclid算法最少要做几次除法?(1次)

b. 对于所有1≤m,n≤10的输入, Euclid算法最多要做几次除法?(5次)

gcd(5,8)

习题1.2

1.(农夫过河)

P—农夫W—狼G—山羊C—白菜

2.(过桥问题)

1,2,5,10---分别代表4个人, f—手电筒

4. 对于任意实系数a,b,c, 某个算法能求方程ax^2+bx+c=0的实根,写出上述算法的伪代码(可以假设sqrt(x)是求平方根的函数)

算法Quadratic(a,b,c)

//求方程ax^2+bx+c=0的实根的算法

//输入:实系数a,b,c

//输出:实根或者无解信息

If a≠0

D←b*b-4*a*c

If D>0

temp←2*a

x1←(-b+sqrt(D))/temp

x2←(-b-sqrt(D))/temp

return x1,x2

else if D=0 return –b/(2*a)

else return ―no real roots‖

else //a=0

if b≠0 return –c/b

else //a=b=0

if c=0 return ―no real numbers‖

else return ―no real roots‖

5. 描述将十进制整数表达为二进制整数的标准算法

a.用文字描述

b.用伪代码描述

解答:

a.将十进制整数转换为二进制整数的算法

输入:一个正整数n

输出:正整数n相应的二进制数

第一步:用n除以2,余数赋给Ki(i=0,1,2...),商赋给n

第二步:如果n=0,则到第三步,否则重复第一步

第三步:将Ki按照i从高到低的顺序输出

b.伪代码

算法DectoBin(n)

//将十进制整数n转换为二进制整数的算法

//输入:正整数n

//输出:该正整数相应的二进制数,该数存放于数组Bin[1...n]中

i=1

while n!=0 do {

Bin[i]=n%2;

n=(int)n/2;

i++;

}

while i!=0 do{

print Bin[i];

i--;

}

9.考虑下面这个算法,它求的是数组中大小相差最小的两个元素的差.(算法略) 对这个算法做尽可能多的改进.

算法MinDistance(A[0..n-1])

//输入:数组A[0..n-1]

//输出:the smallest distance d between two of its elements

习题1.3

考虑这样一个排序算法,该算法对于待排序的数组中的每一个元素,计算比它小的元素个数,然后利用这个信息,将各个元素放到有序数组的相应位置上去.

a.应用该算法对列表‖60,35,81,98,14,47‖排序

b.该算法稳定吗?

c.该算法在位吗?

解:

a. 该算法对列表‖60,35,81,98,14,47‖排序的过程如下所示:

b.该算法不稳定.比如对列表‖2,2*‖排序

c.该算法不在位.额外空间for S and Count[]

4.(古老的七桥问题)

习题1.4

1.请分别描述一下应该如何实现下列对数组的操作,使得操作时间不依赖数组的长度.

a.删除数组的第i个元素(1<=i<=n)

b.删除有序数组的第i个元素(依然有序)

hints:

a. Replace the ith element with the last element and decrease the array size of 1

b. Replace the ith element with a special symbol that cannot be a value of the array’s element(e.g., 0 for an array of positive numbers ) to mark the ith position is empty.

(―lazy deletion‖)

习题2.1

1

欧几里得算法的时间复杂度

欧几里得算法, 又称辗转相除法, 用于求两个自然数的最大公约数. 算法的思想很简单, 基于下面的数论等式

gcd(a, b) = gcd(b, a mod b)

其中gcd(a, b)表示a和b的最大公约数, mod是模运算, 即求a除以b的余数. 算法如下:

输入: 两个整数a, b

输出: a和b的最大公约数

function gcd(a, b:integer):integer;

if b=0 return a;

else return gcd(b, a mod b);

end function

欧几里得算法是最古老而经典的算法, 理解和掌握这一算法并不难, 但要分析它的时间复杂度却并不容易. 我们先不考虑模运算本身的时间复杂度(算术运算的时间复杂度在Knuth的TAOCP中有详细的讨论), 我们只考虑这样的问题: 欧几里得算法在最坏情况下所需的模运算次数和输入的

a 和

b 的大小有怎样的关系?

我们不妨设a>b>=1(若a=2), 显然, 若算法需要n 次模运算, 则有un=gcd(a, b), un+1=0. 我们比较数列{un}和菲波那契数列{Fn}, F0=1<=un, F1=1<=un-1, 又因为由uk mod uk+1=uk+2, 可得uk>=uk+1+uk+2, 由数学归纳法容易得到uk>=Fn-k, 于是得到a=u0>=Fn, b=u0>=Fn-1. 也就是说如果欧几里得算法需要做n 次模运算, 则b 必定不小于Fn-1. 换句话说, 若 b(1.618)n/sqrt(5), 即b>(1.618)n/sqrt(5), 所以模运算的次数为O(lgb)---以b 为底数 = O(lg(2)b)---以2为底数,输入规模也可以看作是b 的bit 位数。

习题2.2

7.对下列断言进行证明:(如果是错误的,请举例) a. 如果t(n)∈O(g(n),则g(n)∈Ω(t(n)) b.α>0时,Θ(αg(n))= Θ(g(n)) 解:

a. 这个断言是正确的。它指出如果t(n)的增长率小于或等于g(n)的增长率,那么 g(n)的增长率大于或等于t(n)的增长率

由 t(n)≤c ·g(n) for all n ≥n0, where c>0

则:)

()()1

(n g n t c ≤ for all n ≥n0

b. 这个断言是正确的。只需证明))(())(()),(())((n g n g n g n g ααΘ?ΘΘ?Θ。 设f(n)∈Θ(αg(n)),则有:

)()(n g c n f α≤ for all n>=n0, c>0

)()(1n g c n f ≤ for all n>=n0, c1=c α>0

即:f(n)∈Θ(g(n))

又设f(n)∈Θ(g(n)),则有:)()(n cg n f ≤ for all n>=n0,c>0

)

()()(1n g c n g c

n f ααα

=≤

for all n>=n0,c1=c/α>0

即:f(n)∈Θ(αg(n))

8.证明本节定理对于下列符号也成立: a.Ω符号 b.Θ符号 证明:

a 。we need to proof that if t1(n)∈Ω(g1(n)) and t2(n)∈Ω(g2(n)), then t1(n)+ t2(n)∈Ω(max{g1(n), g2(n)})。

由 t1(n)∈Ω(g1(n)),

t1(n)≥c1g1(n) for all n>=n1, where c1>0 由 t2(n)∈Ω(g2(n)),

T2(n)≥c2g2(n) for all n>=n2, where c2>0 那么,取c>=min{c1,c2},当n>=max{n1,n2}时: t1(n)+ t2(n)≥c1g1(n)+ c2g2(n) ≥c g1(n)+c g2(n)≥c[g1(n)+ g2(n)] ≥cmax{ g1(n), g2(n)} 所以以命题成立。

b. t1(n)+t2(n) ∈Θ()))(2),(1max (n g n g

证明:由大?的定义知,必须确定常数c1、c2和n0,使得对于所有n>=n0,有:

))(2),(1max ()(2)(1))(2),(1max ((1n g n g n t n t n g n g c ≤+≤

由t1(n)∈Θ(g1(n))知,存在非负整数a1,a2和n1使: a1*g1(n)<=t1(n)<=a2*g1(n)-----(1) 由t2(n)∈Θ(g2(n))知,存在非负整数b1,b2和n2使: b1*g2(n)<=t2(n)<=b2*g2(n)-----(2) (1)+(2): a1*g1(n)+ b1*g2(n)<=t1(n)+t2(n) <= a2*g1(n)+ b2*g2(n) 令c1=min(a1,b1),c2=max(a2,b2),则

C1*(g1+g2)<= t1(n)+t2(n) <=c2(g1+g2)-----(3) 不失一般性假设max(g1(n),g2(n))=g1(n). 显然,g1(n)+g2(n)<2g1(n),即g1+g2<2max(g1,g2) 又g2(n)>0,g1(n)+g2(n)>g1(n),即g1+g2>max(g1,g2)。 则(3)式转换为: C1*max(g1,g2) <= t1(n)+t2(n) <=c2*2max(g1,g2) 所以当c1=min(a1,b1),c2=2c2=2max(c1,c2),n0=max(n1,n2)时,当n>=n0时上述不等式成立。 证毕。

10. 切忌算法走的步数和人真实走的步数的区别,算法是不需要走回头路的。

习题2.4

解下列递推关系 (做a,b ) a.

解:

??

?=+-=0)1(5

)1()(x n x n x 当n>1时

b. 解:

对于计算n!的递归算法F(n),建立其递归调用次数的递推关系并求解。 解:

考虑下列递归算法,该算法用来计算前n 个立方的和:S(n)=13+23+…+n3。 算法S(n)

//输入:正整数n //输出:前n 个立方的和 if n=1 return 1

else return S(n-1)+n*n*n

a. 建立该算法的基本操作次数的递推关系并求解

b. 如果将这个算法和直截了当的非递归算法比,你做何评价? 解:

a.

??

?=-=4

)1()1(3)(x n x n x 当n>1时

6. 汉诺塔的非递归问题请见F:\work\继续教育\算法设计与分析基础

7. a. 请基于公式2n=2n-1+2n-1,设计一个递归算法。当n是任意非负整数的时候,该算法能够计算2n的值。

b. 建立该算法所做的加法运算次数的递推关系并求解

c. 为该算法构造一棵递归调用树,然后计算它所做的递归调用次数。

d. 对于该问题的求解来说,这是一个好的算法吗?

解:

a.算法power(n)

//基于公式2n=2n-1+2n-1,计算2n

//输入:非负整数n

//输出: 2n的值

If n=0 return 1

Else return power(n-1)+ power(n-1)

c.

∑=+-==n

i n i n C 0

11

22)(

8.考虑下面的算法

算法 Min1(A[0..n-1])

//输入:包含n 个实数的数组A[0..n-1] If n=1 return A[0]

Else temp ←Min1(A[0..n-2]) If temp ≤A[n-1] return temp Else return A[n-1] a.该算法计算的是什么?

b.建立该算法所做的基本操作次数的递推关系并求解 解:

a.计算的给定数组的最小值

b.??

?+-=01

)1()(n C n C

9.考虑用于解决第8题问题的另一个算法,该算法递归地将数组分成两半.我们将它称为Min2(A[0..n-1]) 算法 Min(A[r..l]) If l=r return A[l]

Else temp1←

Min2(A[l..(l+r)/2])

Temp2←Min2(A[l..(l+r)/2]+1..r) If temp1≤temp2 return temp1 Else return temp2

a.建立该算法所做的的操作次数的递推关系并求解

b.算法Min1和Min2哪个更快?有其他更好的算法吗? 解: a.

for all n>1

n=1

习题2.5

4.

假设n格梯子有f(n)种方法。

则:

f(1) = 1

f(2) = 2

对n>2,有:

f(n) = (先上一格,再上n-1格的方法数)+ (先上两格,再上n-2格的方法数)即

f(n) = f(n-1) + f(n-2)

所以f(n)是Fibonacci数列的第n+1项?

#include

long fib(int n)

{ if (n == 1 || n == 2) return 1;

return fib(n - 1) + fib(n - 2);

}

main()

{ int n;

scanf("%d", &n);

printf("%ld\n", fib(n+1));

return 0;

}

习题2.6

考虑下面的排序算法,其中插入了一个计数器来对关键比较次数进行计数.

算法SortAnalysis(A[0..n-1])

//input:包含n个可排序元素的一个数组A[0..n-1]

//output:所做的关键比较的总次数

count←0

for i←1 to n-1 do

v←A[i]

j←i-1

while j>0 and A[j]>v do

count←count+1

A[j+1]←A[j]

j←j+1

A[j+1]←v

return count

比较计数器是否插在了正确的位置?如果不对,请改正.

解:应改为:

算法SortAnalysis(A[0..n-1])

//input:包含n个可排序元素的一个数组A[0..n-1]

//output:所做的关键比较的总次数

count←0

for i←1 to n-1 do

v←A[i]

j←i-1

while j>=0 and A[j]>v do

count←count+1

A[j+1]←A[j]

j←j-1

if j>=0 count=count+1

A[j+1]←v

return count

7. b gcd(m,n)算法性能最坏情况下为两个整数为斐波那锲数列,即k时间最长时,最小的整数对必定为斐波那锲数列。

9. 我认为埃拉托色尼筛的效率为根号n。

10. gcd(a,b)复杂性估计

c = a % b ; c < a/2; 在算法中即表现为n(余数)每两次循环至少减少为原来的一半,所以该算法时间复杂度估算为2logn = O( logn ); 由于能力有限,更精确复杂的时间复杂度的计算还没有掌握。在最坏的情况下(如m和n是两个相邻的斐波那契数时)可以稍微改进成1.44logn。欧几里德算法在平均情况下的性能需要大量篇幅的高度复杂的数学分析,其迭代的平均次数约为(12ln2lnn)/pi2+1.47。

习题3.1

4. a.设计一个蛮力算法,对于给定的x0,计算下面多项式的值: P(x)=anxn+an-1xn-1+…+a1x+a0 并确定该算法的最差效率类型.

b.如果你设计的算法属于Θ(n2),请你为该算法设计一个线性的算法. C.对于该问题来说,能不能设计一个比线性效率还要好的算法呢? 解:

Algorithms BruteForcePolynomialEvaluation(P[0..n],x) //由高幂到低幂用蛮力法计算多项式p 在给定点x 的值 //输入:P[0..n]是多项式按低幂到高幂的常系数,以及定值x //输出: 多项式p 在给定点x 的值 p=0.0

for i=n to 0 do power=1

for j=1 to i do power=power*x p=p+P[i]*power return p

算法效率分析:

基本操作:两个数相乘,且M(n)仅依赖于多项式的阶n

∑∑∑===Θ∈+=

==n i n

i i j n n n i n M 020

1

)(2)

1(1)(

tha above algorithms is very inefficient, because we recompute powers of x again and again as if there

were no relationship among them.In fact ,we can move from the lowest term to the highest and compute xi by using xi-1.

Algorithms BetterBruteForcePolynomialEvaluation(P[0..n],x) //由高幂到低幂用蛮力法计算多项式p 在给定点x 的值 //输入:P[0..n]是多项式按低幂到高幂的常系数,以及定值x //输出: 多项式p 在给定点x 的值 P=P[0] power=1

for i←1 to n do

power←power*x p←p+P[i]*power return p

基本操作乘法运算总次数M(n):

)

(22)(1

n n n M n

i Θ∈==∑=

c.不行.因为计算任意一个多项式在任意点x 的值,都必须处理它的n+1 个系数.例如: (x=1,p(x)=an+an-1+..+a1+a0,至少要做n 次加法运算) 5.应用选择排序对序列example 按照字母顺序排序.

6.选择排序是稳定的吗?(不稳定)

回到主题,现在分析一下常见的排序算法的稳定性,每个都给出简单的理由。

(1)冒泡排序

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

(2)选择排序

选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。

(3)插入排序

插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

(4)快速排序

快速排序有两个方向,左边的i下标一直往右走,当a[i] <= a[center_index],其中center_index 是中枢元素的数组下标,一般取为数组第0个元素。而右边的j下标一直往左走,当a[j] > a[center_index]。如果i和j都走不动了,i <= j, 交换a[i]和a[j],重复上面的过程,直到i>j。交换a[j]和a[center_index],完成一趟快速排序。在中枢元素和a[j]交换的时候,很有可能把前面的元素的稳定性打乱,比如序列为5 3 3 4 3 8 9 10 11,现在中枢元素5和3(第5个元素,下标从1开始计)交换就会把元素3的稳定性打乱,所以快速排序是一个不稳定的排序算法,不稳定发生在中枢元素和a[j]交换的时刻。

(5)归并排序

归并排序是把序列递归地分成短序列,递归出口是短序列只有1个元素(认为直接有序)或者2个序列(1次比较和交换),然后把各个有序的段序列合并成一个有序的长序列,不断合并直到原序列全部排好序。可以发现,在1个或2个元素时,1个元素不会交换,2个元素如果大小相等也没有人故意交换,这不会破坏稳定性。那么,在短的有序序列合并的过程中,稳定是是否受到破坏?没有,合并过程中我们可以保证如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,这样就保证了稳定性。所以,归并排序也是稳定的排序算法。

(6)基数排序

基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高

位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。基数排序基于分别排序,分别收集,所以其是稳定的排序算法。

(7)希尔排序(shell)

希尔排序是按照不同步长对元素进行插入排序,当刚开始元素很无序的时候,步长最大,所以插入排序的元素个数很少,速度很快;当元素基本有序了,步长很小,插入排序对于有序的序列效率很高。所以,希尔排序的时间复杂度会比o(n^2)好一些。由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的。

(8)堆排序

我们知道堆的结构是节点i的孩子为2*i和2*i+1节点,大顶堆要求父节点大于等于其2个子节点,小顶堆要求父节点小于等于其2个子节点。在一个长为n的序列,堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。但当为n/2-1, n/2-2, ...1这些个父节点选择元素时,就会破坏稳定性。有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,那么这2个相同的元素之间的稳定性就被破坏了。所以,堆排序不是稳定的排序算法。

7.用链表实现选择排序的话,能不能获得和数组版相同的Θ(n2)效率?

Yes.Both operation—finding the smallest element and swapping it –can be done as efficiently with the linked list as with an array.

9.a.请证明,如果对列表比较一遍之后没有交换元素的位置,那么这个表已经排好序了,算法可以停止了.

b.结合所做的改进,为冒泡排序写一段伪代码.

c.请证明改进的算法最差效率也是平方级的.

Hints:

第i趟冒泡可以表示为:

如果没有发生交换位置,那么:

b.Algorithms BetterBubblesort(A[0..n-1])

//用改进的冒泡算法对数组A[0..n-1]排序

//输入:数组A[0..n-1]

//输出:升序排列的数组A[0..n-1]

count←n-1 //进行比较的相邻元素对的数目

flag←true //交换标志

while flag do

flag←false

for i=0 to count-1 do

if A[i+1]

swap(A[i],A[i+1])

flag←true

count←count-1

c最差情况是数组是严格递减的,那么此时改进的冒泡排序会蜕化为原来的冒泡排序.

10.冒泡排序是稳定的吗?(稳定)

习题3.2

对限位器版的顺序查找算法的比较次数:

在最差情况下

在平均情况下.假设成功查找的概率是p(0<=p<=1)

Hints:

Cworst(n)=n+1

在成功查找下,对于任意的I,第一次匹配发生在第i个位置的可能性是p/n,比较次数是i.在查找不成功时,比较次数是n+1,可能性是1-p.

4. 本题翻译有问题,原题类似与:

前一段时间看到一道Google 的面试题在各大论坛被炒得很火,题目如下:―有一个100层高的大厦,你手中有两个相同的玻璃围棋子。从这个大厦的某一层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略,来得知那个临界层面。‖题目虽然看起来简单,但是仔细想想,此题中蕴含的算法道理以及实用价值还是很值得好好研究一下。石头在网上也看到了不少热心朋友的解法(CSDN、ChinaUnix),看过之后感觉还是挺有启发的,于是总结一下,主要的算法有以下几种:

<1> 等分段求最小值:这种算法先假设把大楼分成等高的 x 段,这样在最差的情况下,要确定临界段,我们需要投掷100/x-1 次,确定了临界段之后要确定临界层,我们需要再投掷x-1 次。这样,问题就成了求函数f(x)=(100/x-1)+(x-1) 的最小值问题。由于f(x) 存在最小值且只有一个驻点,所以当x=10 时f(x) 取得最小值,最小值为18。<2> 假设投掷次数是均匀分布的,那么为了使最坏情况的投掷数最小,我们希望无论临界段在哪里,总的投掷数都不变(也就是说将投掷数均匀分布)。这样我们就可以假设第一次投掷的层数是f,转化成数学模型,可以得到如下方程式f+(f-1)+...+2+1>=99,即f(f+1)/2>=99 的最小整数解,解出结果等于14。程序算法如下:按结果分析看来,方法一的最小值的确比较小(10)但是问题是最大值无法确定(比如假设临界层在第99层则需要仍19下);而方法二的算法好在能得出一个固定的临界层值,这样便于一些问题的处理。总的来说,石头认为两种方法各有所长,虽然方法二看起来的确更接近出题者的本意,但是如果将棋子本身破碎的概率也考虑进去就不一定了(当然,一般来说层数越高破碎的概率应该越大,但是我们试想一下如果假设棋子破碎的几率是和层数成反比,那么使用方法一是否会有更好的效果呢?)。然而不管出题者的意图是什么,我觉得这个题目所引出的数学模型还是很有实用意义的,特别在一些数据挖掘应用中。我猜想这些算法是不是与Google 数据库的技术内幕有什么联系呢... 前几天和一个业内的前辈谈起下一代互联网的技术趋势,说到了所谓的―算法时代‖的话题,看来关注一些有趣的算法也不错呢... 不知不觉时间又晚了,还是先休息吧:)

6.给出一个长度为n的文本和长度为m的模式构成的实例,它是蛮力字符串匹配算法的一个最差输入.并指出,对于这样的输入需要做多少次字符比较运算.

Hints:

文本:由n个0组成的文本

模式:前m-1个是0,最后一个字符是1

比较次数: m(n-m+1)

7.为蛮力字符匹配算法写一个伪代码,对于给定的模式,它能够返回给定的文本中所有匹配子串的数量.

Algorithms BFStringmatch(T[0..n-1],P[0..m-1])

//蛮力字符匹配

//输入:数组T[0..n-1]—长度为n的文本,数组P[0..m-1]—长度为m的模式

//输出:在文本中匹配成功的子串数量

count←0

for i←0 to n-m do

j←0

while j

j←j+1

if j=m

count←count+1

return count

8.如果所要搜索的模式包含一些英语中较少见的字符,我们应该如何修改该蛮力算法来利用这个信息.

Hint:每次都从这些少见字符开始比较,如果匹配, 则向左边和右边进行其它字符的比较.

习题3.3

奇数派问题:

证明如下:

容易验证当n=3时成立;假设n=k时如果成立,那当n=k+2时,k+2个人记为点A1,A2,…,A(k+2),d=min(AiAj),不妨设A(k+1)A(k+2)的距离为d,则A(k+1)和A(k+2)相互是距离最近的点,收到彼此的派:如果A(k+1)和A(k+2)还收到其他人的派,其他k个人至多有k-1个派,利用抽屉原理,其他k个人中必有一个人没有派;如果A(k+1)和A(k+2)没有收到其他人的派,其他k个人相互在掷派,利用归纳假设,其他k个人中必有一个没有派,n=k+2时命题成立。

7. 凸包问题

找那些x、y坐标最小或者最大的

10.该问题可以用下图表示:

该问题即转化为把3x+5y这条直线平行移动,越在上面k值越大,即转为求阴影部分的某个极点。习题3.4

注意该题的假设(所以不需要排列组合算法再去生成旅行线路),只需要对每条线路求出最短路径的长度再比较这些路径,所以,该问题的基本操作为加法。

下面谈谈排列组合的递归和非递归算法:(一时兴起,与本题无关)

全排列的递归算法

给定数字1~n,输出从中选出m个数的排列和组合。

为了简单起见,采用递归算法来描述,首先解决排列问题:

这个算法不太漂亮,用到了两个全局变量:

int ARR[] = { 1,2,3,4,5}; // 用来输出的全局缓冲区

int PERM_LEN; // 排列的长度

void permutation( int arr[], int n, int m )

{

int i;

if( m== 0 )

{

for(i=0;i

printf(" %d",ARR[i]);

printf("\n");

return;

}

for(i=0; i

{

swap( arr[i], arr[0] );

permutation( arr+1, n-1, m-1 );

swap( arr[i], arr[0] );

}

}

算法比较简单,不详细说明了。

组合的递归算法

void comb( int n, int m ,int buff[], int count )

{

if( m == 0 )

{// 递归退出条件,打印回车

for( int i=0;i

printf("%d ", buff[i] );

printf("\n");

return;

}

for( int i=0; i<= n - m; ++i )

{

buff[count++] = n-i;

comb( n-i-1, m-1,buff,count );

--count;

}

}

2. 假设输入n个顶点用数组表示为v[n],而输入的路径权重用二维数组t表示

找出全排列的一半,即所有排列中只考虑v[1]在v[2]前面的排列,

假设每种排列存入临时数组K,用S寄存最小路径。对每个排列,执行(2)

算出排列的路径长度,如排列为k[n],路径长度为q=t[k[0],k[1]]+

t[k[1],k[2]]+……,如果该长度小于S,则S为q。

3.根据图论,连通图是否具有欧拉回路的充要条件是:G的每一个顶点的度是偶数。所以,只要判断邻接矩阵中每行的和是否是偶数即可。

很容易得到这样一个分配实例,用它的成本矩阵描述为

1 2

2 9

该分配只有两种方案,1+9或者2+2

(1) 求出n个正整数的和K,如K为奇数,肯定无解。

如为偶数,取K/2。

(2) 对n个数进行排序,编号为a1 …an,最大数编号为n。

(3) 子集中元素个数为1,从an开始找,直到ak

(4) 子集中元素个数为2,生成所有子集个数并穷举查找和为k/2的子集。

(5)子集中元素个数为P,生成所有子集个数并穷举查找和为k/2的子集。

……

直到检查到P=n/2取整即可。

方法一:

对图节点进行编号,生成所有K的子集

判断子集中的元素是否两两相连,直到找到这样的子集为止

如果找不到这样的子集就表示没有k的完备子图。

的完备子图。

方法二:

先对图的节点进行编号

然后用下列回溯法找:

如先从1号开始,找到连接1号且数字最小的点,如为q,则目前的序列为

1,p,接着找与1数字次小的点,为q,判断q是否与p相连,如有,继续找,没有,序列退到1,继续找与1相连的q,再找与1相连的m等等…….

直找到序列中的点数为K为止,如与1所有的点都找遍了,再从2开始。

总而言之,如果存在这样的完备子图,肯定能够按节点序号排列,所以,以上的方法,后续序列节点的值也要找比序列中所有的值大的以节省时间。(如q>p)

枚举所有的排列,看看是否有序。

(1)穷举法:枚举所有的幻方组合,看看是否满足条件

(2)网上幻方制作方法:(Magic_Square.pdf)

(1)穷举所有的对应表,按对应表把算式进行对应,如果的确相等,即该算数对应正确。题中字母共有8个,即所有情况为从10个字母中选出8个,同时S M

不能为0,即取时的方法共为9(s不能为0)*8(m不能为0)*8!种。

(2)见https://www.360docs.net/doc/3115421520.html,/wiki/Verbal_arithmetic。

The solution to this puzzle is O = 0, M = 1, Y = 2, E = 5, N = 6, D = 7, R = 8, and S = 9

用回溯法

豪无疑问,M肯定为1,而S必定为9,或者8,S为9时,推出o必定为0,就这样一步步推下去,不行就回溯。

习题4.1

1.a.为一个分治算法编写伪代码,该算法求一个n个元素数组中最大元素的位置.

b.如果数组中的若干个元素都具有最大值,该算法的输出是怎样的呢?

c.建立该算法的键值比较次数的递推关系式并求解.

d.请拿该算法与解同样问题的蛮力算法做一个比较

解:a.

Algorithms MaxIndex(A[l..r]){

Input:A portion of array A[0..n-1] between indices l and r(l≤r)

Output: The index of the largest element in A[l..r]

if l=r return l

else temp1←MaxIndex(A[l..(l+r)/2])

temp2←MaxIndex(A[(l+r)/2..r])

if A[temp1]≥A[temp2]return temp1

else return temp2

}

b.返回数组中位于最左边的最大元素的序号.

c.键值比较次数的递推关系式:

C(n)=C( n/2 )+C( n/2 )+1 for n>1

C(1)=0

设n=2k,C(2k)=2C(2k-1)+1

=2[2 C(2k-2)+1]+1=22C(2k-2)+2+1

=2[22C(2k-3)+1]+2+1=23C(2k-3)+ 22+2+1

=...

=2iC(2k-i)+ 2i-1+2 i-2 +...+2+1

=...

=2kC(2k-k)+ 2k-1+2 k-2 +...+2+1=2k-1=n-1

可以证明C(n)=n-1对所有n>1的情况都成立(n是偶数或奇数)

d.比较的次数相同,但蛮力算法不用递归调用。

2、a.为一个分治算法编写伪代码,该算法同时求出一个n元数组的最大元素和最小元素的值。

b.请拿该算法与解同样问题的蛮力算法做一个比较。

c.请拿该算法与解同样问题的蛮力算法做一个比较。

解答:

a.同时求出最大值和最小值,只需要将原数组一分为二,再使用相同的方法找出这两个部分中的最大值和最小值,然后经过比较就可以得到整个问题的最大值和最小值。

算法MaxMin(A[l..r],Max,Min)

//该算法利用分治技术得到数组A中的最大值和最小值

//输入:数值数组A[l..r]

//输出:最大值Max和最小值Min

if(r=l) Max←A[l];Min←A[l]; //只有一个元素时

else

if r-l=1 //有两个元素时

if A[l]≤A[r]

Max←A[r]; Min←A[l]

else

《计算机算法设计与分析》习题及答案

《计算机算法设计与分析》习题及答案 一.选择题 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。随机数函数 D.搜索函数 19. (D)是贪心算法与动态规划算法的共同点。 A、重叠子问题 B、构造最优解 C、贪心选择性质 D、最优子结构性质 20. 矩阵连乘问题的算法可由( B )设计实现。 A、分支界限算法 B、动态规划算法 C、贪心算法 D、回溯算法 21. 分支限界法解旅行售货员问题时,活结点表的组织形式是( A )。

中科院陈玉福计算机算法设计与分析期末简答题答案

1. 贪心算法和动态规划算法有什么共同点和区别?它们都有那些优势和劣势? 共通点:动态规划和贪心算法都是一种递推算法,均有局部最优解来推导全局最优解 区别:贪心算法中,作出的每步贪心决策都无法改变,每一步的最优解一定包含上一步的 最优解,而上一部之前的最优解则不作保留。 动态优化算法,全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解 动态规划算法利用子问题重叠性质,对每一个子问题只计算一次,将其解保存在一个表格中。不同的子问题个数随着输入问题的规模呈多项式增长,因此,动态规划算法通常只需要多项式时间,从而获得较高的解题效率。但它需要计算之前所有情况花费,更加耗费空间。 贪心算法所作的选择依赖于以往所作过的选择,但决不依赖于将来的选择,这使得算法在编 码和执行过程中都有一定的速度优势。贪心算法是只是找局部最优解,不一定是全局最优解。 2. 试比较回溯法与分枝限界算法,分别谈谈这两个算法比较适合的问题? 二者都是在解空间树里搜索问题的可靠解或最优解,但是搜索的方式不同,回溯法采用深 度优先的方式,直到达到问题的一个可行解,或经判断沿此路径不会达到问题的可行解或最优解时,停止向前搜索,并沿原路返回到该路径上最后一个还可扩展的节点,然后,从该节点出发朝新的方向纵深搜索。分枝限界法采用的是宽度优先的方式,它将活节点存放在一个特殊的表中,其策略是,在扩展节点处,首先生成其所有的儿子节点,将那些导致不可行解或导致非最优解的儿子节点舍弃,其余儿子节点加入活节点表中,然后,从活节点中取出一个节点作为当前扩展节点,重复上述节点中扩展过程。可以看出,回溯法一般用于求问题的一个可行解,而分枝限界可以用于求出问题的所有可行解。 3. 何谓最优化原理?采用动态规划算法必须满足的条件是什么?动态规划算法是通过什 么问题的什么特性提高效率的? 一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质。最优子结构性质,子问题重叠性质是计算模型采用动态规划算法求解的两个基本要素。 动态规划算法利用子问题重叠性质,对每一个子问题只计算一次,将其解保存在一个表格中。不同的子问题个数随着输入问题的规模呈多项式增长,因此,动态规划算法通常只需要多项式时间,从而获得较高的解题效率 4. 什么是多项式时间算法? 若存在一个常数C,使得对于所有n>=0,都有|f(n)| <= C*|g(n)|,则称函数f(n)是O(g(n))。时间复杂度是O(p(n))的算法称为多项式时间算法,这里p(n)是关于n的多项式。 时间复杂度为O(nlog(n))、O(n^3)的算法都是多项式时间算法,时间复杂度为O(n^log(n))、O(n!)、O(2^n)的算法是指数时间算法。 一个优化问题如果已经找到了多项式时间算法,则称该问题为多项式时间可解问题,并 将这类问题的集合记为P,因此多项式时间可解问题就称为P类问题。。

算法设计与分析复习题目及答案19874

一。选择题 1、二分搜索算法就是利用( A )实现的算法。 A、分治策略B、动态规划法C、贪心法 D、回溯法 2、下列不就是动态规划算法基本步骤的就是( A )。 A、找出最优解的性质 B、构造最优解 C、算出最优解 D、定义最优解 3、最大效益优先就是( A )的一搜索方式。 A、分支界限法B、动态规划法C、贪心法D、回溯法 4、在下列算法中有时找不到问题解的就是( B )。 A、蒙特卡罗算法 B、拉斯维加斯算法 C、舍伍德算法 D、数值概率算法 5、回溯法解旅行售货员问题时的解空间树就是( B )。 A、子集树???B、排列树C、深度优先生成树?D、广度优先生成树 6.下列算法中通常以自底向上的方式求解最优解的就是( B)。 A、备忘录法?B、动态规划法?C、贪心法????D、回溯法 7、衡量一个算法好坏的标准就是(C )。?A 运行速度快B占用空间少 C 时间复杂度低 D 代码短?8、以下不可以使用分治法求解的就是(D )。?A棋盘覆盖问题B选择问题 C 归并排序 D 0/1背包问题?9、实现循环赛日程表利用的算法就是( A )。 A、分治策略?? B、动态规划法 C、贪心法??D、回溯法 10、下列随机算法中运行时有时候成功有时候失败的就是(C ) A 数值概率算法 B 舍伍德算法 C 拉斯维加斯算法 D 蒙特卡罗算法 11.下面不就是分支界限法搜索方式的就是( D )。 A、广度优先?B、最小耗费优先C、最大效益优先D、深度优先 12、下列算法中通常以深度优先方式系统搜索问题解的就是( D )。 A、备忘录法B、动态规划法??C、贪心法???D、回溯法

13、备忘录方法就是那种算法的变形。( B ) A、分治法? B、动态规划法? C、贪心法?? D、回溯法 14、哈弗曼编码的贪心算法所需的计算时间为( B )。 A、O(n2n)?? B、O(nlogn)? C、O(2n) ??? D、O(n) 15.分支限界法解最大团问题时,活结点表的组织形式就是( B )。 A、最小堆???? B、最大堆?? C、栈???D、数组 16.最长公共子序列算法利用的算法就是( B )。 A、分支界限法? B、动态规划法? C、贪心法 D、回溯法 17.实现棋盘覆盖算法利用的算法就是( A )。 A、分治法??B、动态规划法C、贪心法??D、回溯法 18、下面就是贪心算法的基本要素的就是( C )。 A、重叠子问题?B、构造最优解??C、贪心选择性质??D、定义最优解 19.回溯法的效率不依赖于下列哪些因素( D ) A、满足显约束的值的个数????B、计算约束函数的时间 C、计算限界函数的时间?? D、确定解空间的时间 20、下面哪种函数就是回溯法中为避免无效搜索采取的策略( B ) A.递归函数?B、剪枝函数? C。随机数函数???D、搜索函数 21、下面关于NP问题说法正确的就是(B )?A NP问题都就是不可能解决的问题?B P类问题包含在NP类问题中?C NP完全问题就是P类问题的子集 D NP类问题包含在P类问题中 22、蒙特卡罗算法就是( B )的一种。 A、分支界限算法 B、概率算法C、贪心算法D、回溯算法 23、下列哪一种算法不就是随机化算法( C ) A、蒙特卡罗算法 B、拉斯维加斯算法 C、动态规划算法 D、舍伍德算法 24、 ( D )就是贪心算法与动态规划算法的共同点。A、重叠子问题B、构造最优解?C、贪心选择性质D、最优子结构性质25、矩阵连乘问题的算法可由( B)设计实现。

算法设计与分析课后部分习题答案

算法实现题3-7 数字三角形问题 问题描述: 给定一个由n行数字组成的数字三角形,如图所示。试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大。编程任务: 对于给定的由n行数字组成的数字三角形,编程计算从三角形的顶至底的路径经过的数字和的最大值。数据输入: 有文件input.txt提供输入数据。文件的第1行是数字三角形的行数n,1<=n<=100。接下来的n行是数字三角形各行的数字。所有数字在0-99之间。结果输出: 程序运行结束时,将计算结果输出到文件output.txt中。文件第1行中的数是计算出的最大值。 输入文件示例输出文件示 例 input.txt output.txt 5 30 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 源程序: #include "stdio.h" voidmain() { intn,triangle[100][100],i,j;//triangle数组用来存储金字塔数值,n表示行数 FILE *in,*out;//定义in,out两个文件指针变量 in=fopen("input.txt","r"); fscanf(in,"%d",&n);//将行数n读入到变量n中

for(i=0;i=0;row--)//从上往下递归计算 for(int col=0;col<=row;col++) if(triangle[row+1][col]>triangle[row+1][col+1]) triangle[row][col]+=triangle[row+1][col]; else triangle[row][col]+=triangle[row+1][col+1]; out=fopen("output.txt","w"); fprintf(out,"%d",triangle[0][0]);//将最终结果输出到output.txt中 } 算法实现题4-9 汽车加油问题 问题描述: 一辆汽车加满油后可行驶nkm。旅途中有若干加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产出一个最优解。编程任务: 对于给定的n和k个加油站位置,编程计算最少加油次数。数据输入: 由文件input.txt给出输入数据。第1行有2个正整数n和k ,表示汽车加满油后可行驶nkm,且旅途中有k个加油站。接下来的1行中,有k+1个整数,表示第k个加油站与第k-1个加油站之间的距离。第

算法设计与分析试卷(2010)

算法设计与分析试卷(A 卷) 一、 选择题 ( 选择1-4个正确的答案, 每题2分,共20分) (1)计算机算法的正确描述是: B 、D A .一个算法是求特定问题的运算序列。 B .算法是一个有穷规则的集合,其中之规则规定了一个解决某一特定类型的问题的运算序列。 C .算法是一个对任一有效输入能够停机的图灵机。 D .一个算法,它是满足5 个特性的程序,这5个特性是:有限性、确定性、能 行性、有0个或多个输入且有1个或多个输出。 (2)影响程序执行时间的因素有哪些? C 、D A .算法设计的策略 B .问题的规模 C .编译程序产生的机器代码质量 D .计算机执行指令的速度 (3)用数量级形式表示的算法执行时间称为算法的 A A .时间复杂度 B .空间复杂度 C .处理器复杂度 D .通信复杂度 (4)时间复杂性为多项式界的算法有: A .快速排序算法 B .n-后问题 C .计算π值 D .prim 算法 (5)对于并行算法与串行算法的关系,正确的理解是: A .高效的串行算法不一定是能导出高效的并行算法 B .高效的串行算法不一定隐含并行性 C .串行算法经适当的改造有些可以变化成并行算法 D. 用串行方法设计和实现的并行算法未必有效 (6)衡量近似算法性能的重要标准有: A A .算法复杂度 B .问题复杂度 C .解的最优近似度 D .算法的策略 (7)分治法的适用条件是,所解决的问题一般具有这些特征: ABCD A .该问题的规模缩小到一定的程度就可以容易地解决; B .该问题可以分解为若干个规模较小的相同问题; C .利用该问题分解出的子问题的解可以合并为该问题的解 D .该问题所分解出的各个子问题是相互独立的。 (8)具有最优子结构的算法有: A .概率算法 B .回溯法 C .分支限界法 D .动态规划法 (9)下列哪些问题是典型的NP 完全问题: A .排序问题 B .n-后问题 C .m-着色问题 D .旅行商问题 (10)适于递归实现的算法有: C A .并行算法 B .近似算法 C .分治法 D .回溯法 二、算法分析题(每小题5分,共10分) (11)用展开法求解递推关系: (12)分析当输入数据已经有序时快速排序算法的不足,提出算法的改进方案。 ???>+-==1 1)1(211)(n n T n n T

算法设计与分析考试题及答案

算法设计与分析考试题及 答案 It was last revised on January 2, 2021

一、填空题(20分) 1.一个算法就是一个有穷规则的集合,其中之规则规定了解决某一特殊类型问题的一系列运算, 此外,算法还应具有以下五个重要特性:确定性有穷性可行性 0个或多个输入一个或多 个输出 2.算法的复杂性有时间复杂性空间复杂性之分,衡量一个算法好坏的标准是时间复杂度高低 3.某一问题可用动态规划算法求解的显着特征是该问题具有最优子结构性质 4.若序列X={B,C,A,D,B,C,D},Y={A,C,B,A,B,D,C,D},请给出序列X和Y的一个最长公共子序列{BABCD}或{CABCD}或{CADCD} 5.用回溯法解问题时,应明确定义问题的解空间,问题的解空间至少应包含一个(最优)解 6.动态规划算法的基本思想是将待求解问题分解成若干_子问题,先求解_子问题,然后从这些 子问题的解得到原问题的解。 7.以深度优先方式系统搜索问题解的算法称为回溯法 背包问题的回溯算法所需的计算时间为o(n*2n) ,用动态规划算法所需的计算时间为o(min{nc,2n}) 9.动态规划算法的两个基本要素是最优子结构_和重叠子问题 10.二分搜索算法是利用动态规划法实现的算法。 二、综合题(50分) 1.写出设计动态规划算法的主要步骤。 ①问题具有最优子结构性质;②构造最优值的递归关系表达式;③最优值的算法描述;④构造 最优解; 2.流水作业调度问题的johnson算法的思想。 ①令N 1={i|a i =b i };②将N 1 中作业按a i 的非减序排序得到N 1 ’,将N 2 中作业按b i 的非增序排序得到N 2’;③N 1 ’中作业接N 2 ’中作业就构成了满足Johnson法则的最优调度。 3.若n=4,在机器M1和M2上加工作业i所需的时间分别为a i 和b i ,且 (a 1,a 2 ,a 3 ,a 4 )=(4,5,12,10),(b 1 ,b 2 ,b 3 ,b 4 )=(8,2,15,9)求4个作业的最优调度方案,并计算最优 值。 步骤为:N1={1,3},N2={2,4}; N 1’={1,3}, N 2 ’={4,2}; 最优值为:38 4.使用回溯法解0/1背包问题:n=3,C=9,V={6,10,3},W={3,4,4},其解空间有长度为3的0-1向量组成,要求用一棵完全二叉树表示其解空间(从根出发,左1右0),并画出其解空间树,计算其最优值及最优解。 解空间为{(0,0,0),(0,1,0),(0,0,1),(1,0,0),(0,1,1),(1,0,1), (1,1,0),(1,1,1)}。 解空间树为: 该问题的最优值为:16 最优解为:(1,1,0)

算法设计与分析习题

《算法设计与分析》习题 第一章算法引论 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) 递归法 汉诺塔问题 void hanoi(int n, int a, int b, int c) {if (n > 0) { hanoi(n-1, a, c, b); move(a,b); hanoi(n-1, c, b, a); } } 兔子序列(fibonaci 数列 ) 递归实现: Int F(int n) { if(n<=2) return 1; else return F(n-1)+ F(n-2); } 上楼梯问题 Int F(int n) { if(n=1) return 1 if(n=2) return 2; else return F(n-1)+ F(n-2); } 整数划分问题 问题描述:将正整数n 表示成一系列正整数之和,n=n1+n1+n3+… 将最大加数不大于m 的划分个数,记作q(n,m)。正整数n 的划分数 p(n)=q(n,n)。 可以建立q(n,m)的如下递归关系: 递归算法: Int q( int n, int m){ if(n<1||m<1) return 0; If((n=1)||(m=1)) return 1; If (n>=<==-+--+=11,1),()1,()1,(1),(1),(m n m n m n m n m m n q m n q n n q n n q m n q

计算机算法设计与分析期末考试复习题

1、二分搜索算法是利用( A )实现的算法。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法 2、下列不是动态规划算法基本步骤的是( A )。 A、找出最优解的性质 B、构造最优解 C、算出最优解 D、定义最优解 3、最大效益优先是( A )的一搜索方式。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 4、最长公共子序列算法利用的算法是( B )。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 5. 回溯法解TSP问题时的解空间树是( A )。 A、子集树 B、排列树 C、深度优先生成树 D、广度优先生成树6.下列算法中通常以自底向上的方式求解最优解的是( B )。 A、备忘录法 B、动态规划法 C、贪心法 D、回溯法 7、衡量一个算法好坏的标准是(C )。 A 运行速度快 B 占用空间少 C 时间复杂度低 D 代码短 8、以下不可以使用分治法求解的是(D )。 A 棋盘覆盖问题 B 选择问题 C 归并排序 D 0/1背包问题 9. 实现循环赛日程表利用的算法是( A )。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法 10、实现最长公共子序列利用的算法是( B )。 A、分治策略 B、动态规划法 C、贪心法 D、回溯法11.下面不是分支界限法搜索方式的是( D )。 A、广度优先 B、最小耗费优先 C、最大效益优先 D、深度优先 12.下列算法中通常以深度优先方式系统搜索问题解的是( D )。 A、备忘录法 B、动态规划法 C、贪心法 D、回溯法 13. 一个问题可用动态规划算法或贪心算法求解的关键特征是问题的( B )。 A、重叠子问题 B、最优子结构性质 C、贪心选择性质 D、定义最优解14.广度优先是( A )的一搜索方式。 A、分支界限法 B、动态规划法 C、贪心法 D、回溯法 15.背包问题的贪心算法所需的计算时间为( B )。

OpenJudge算法设计与分析习题解答

1、硬币面值组合 描述 使用1角、2角、5角硬币组成n 角钱。 设1角、2角、5角的硬币各用了a、b、c个,列出所有可能的a, b, c组合。 输出顺序为:先按c的值从小到大,若c相同则按b的值从小到大。 输入 一个整数n(1 <= n <= 100),代表需要组成的钱的角数。 输出 输出有若干行,每行的形式为: i a b c 第1列i代表当前行数(行数从001开始,固定3个字符宽度,宽度不足3的用0填充),后面3列a, b, c分别代表1角、2角、5角硬币的个数(每个数字固定12个字符宽度,宽度不足的在左边填充空格)。

源代码: #include #include int main(){ int t=1; int i,j,k; int n; scanf("%d",&n); int A=n,B=n/2,C=n/5; for(i=0;i<=C;i++){ for(j=0;j<=B;j++){ for(k=0;k<=A;k++){ if(i*5+j*2+k*1==n){ printf("%03d%12d%12d%12d\n",t,k,j,i); t++; } } } } getchar(); return 0; } 2、比赛排名 描述 5名运动员参加100米赛跑,各自对比赛结果进行了预测:A说:E是第1名。 B说:我是第2名。 C说:A肯定垫底。 D说:C肯定拿不了第1名。

E说:D应该是第1名。 比赛结束后发现,只有获第1名和第2名的选手猜对了,E不是第2名和第3名,没有出现名次并列的情况。 请编程判断5位选手各是第几名。 输入 无 输出 输出要求:按ABCDE的顺序输出5行,其中第1行是A的名次,第2行是B的名次,第3行是C的名次,第4行是D的名次,第5行是E的名次。 样例输入 样例输出 源代码: #include int main() { printf("5\n"); printf("2\n"); printf("1\n"); printf("3\n"); printf("4\n"); return 0; } 3、鸡兔同笼 描述 一个笼子里面关了鸡和兔子(鸡有2只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。

《算法设计与分析》复习题(汇编)

填空 1.直接或间接地调用自身的算法称为 递归 。 2.算法的复杂性是 算法效率 的度量,是评价算法优劣的重要依据。 3.以广度优先或以最小耗费方式搜索问题解的算法称为 分支限界法 。 4.回溯法解题的显著特点是在搜索过程中动态产生问题的解空间。在任何时刻,算法只保存从根结点到当前扩展结点的路径。如果解空间树中从根结点到叶结点的最长路径的长度为h(n),则回溯法所需的计算空间通常为 o(h(n)) 。 5.人们通常将问题的解决方案分为两大类:一类是可以通过执行若干个步骤就能得出问题 6.算法就是一组有穷的 规则 ,它们规定了解决某一特定类型问题的 一系列运算 。 7.在进行问题的计算复杂性分析之前,首先必须建立求解问题所用的计算模型。3个基本计算模型是 随机存取机、 随机存取存储程序机 、 图灵机 。 8.快速排序算法的性能取决于 划分的对称性 。 9.计算机的资源最重要的是 内存 和 运算 资源。因而,算法的复杂性有时间 和 空间 之分。 10.贪心算法总是做出在当前看来 最优 的选择。也就是说贪心算法并不从整体最优考虑,它所做出的选择只是在某种意义上的 局部最优解 。 11.许多可以用贪心算法求解的问题一般具有2个重要的性质: 最优子结构的 性质和 贪心选择的 性质。 12.常见的两种分支限界法为 队列式 和 优先队列式 。 13.解决0/1背包问题可以使用动态规划、回溯法和分支限界法,其中需要排序的是 回溯法 ,不需要排序的是 动态规划和分支限界法 。 14.f ( n ) = 6 × 2n + n 2,f(n)的渐进性态f ( n ) = O ( 2^n )。 15.对于含有n 个元素的排列树问题,最好情况下计算时间复杂性为 ,最坏情况下计算时间复杂性为 n! 。 16.在忽略常数因子的情况下,O 、Ω和Θ三个符号中, Θ 提供了算法运行时间的一个上界。 17.回溯法的求解过程,即在问题的解空间树中,按 深度优先 策略从根结点出发搜索解空间树。 18.分支限界法的求解过程,即在问题的解空间树中,按 广度优先 策略从根结点出发搜索解空间树。 19.多项式10()m m A n a n a n a =+ ++的上界为 2^n 。 20.用分支限界法解布线问题时,对空间树搜索结束的标志是 活结点表为空 。 21.使用回溯法进行状态空间树裁剪分支时一般有两个标准:约束条件和目标函数的界,N 皇后问题和0/1背包问题正好是两种不同的类型,其中同时使用约束条件和目标函数的界进

算法设计与分析课后习题

第一章 1. 算法分析题 算法分析题1-1 求下列函数的渐进表达式 (1). 3n^2 + 10n < 3n^2 + 10n^2 = 13n^2 = O(n^2) (2). n^2 / 10 + 2^n 当n>5是,n^2 < 2 ^n 所以,当n >= 1时,n^2/10 < 2 ^n 故: n^2/10 + 2^n < 2 ^n + 2^n = 2*2^n = O(2^n) (3). 21 + 1/n < 21 + 1 = 22 = O(1) (4). log(n^3)=3log(n)=O(log(n)) (5). 10log(3^n) = (10log3)n = O(n) 算法分析题1-6 (1)因为:f(n)=log(n^2) = 2log(n); g(n) = log(n) + 5 所以:f(n)=Θ(log(n)+5) =Θ(g(n)) (2)因为:log(n) < √n ; f(n) = 2log(n); g(n)= √n 所以:f(n) = O(g(n)) (3)因为:log(n) < n; f(n) = n; g(n) = log(n^2) = 2log(n) 所以;f(n) = Ω(g(n)) (4)因为:f(n) = nlogn +n; g(n) = logn 所以:f(n) =Ω(g(n)) (5)因为: f(n) = 10; g(n) = log(10) 所以:f(n) =Θ(g(n)) (6)因为: f(n)=log^2(n); g(n) = log(n) 所以: f(n) ==Ω(g(n)) (7)因为: f(n) = 2^n < 100*2^n; g(n)=100n^2; 2^n > n ^2 所以: f(n) = Ω(g(n)) (8)因为:f(n) = 2^n; g(n) = 3 ^n; 2 ^n < 3 ^n 所以: f(n) = O(g(n)) 习题1-9 证明:如果一个算法在平均情况下的计算时间复杂性为Θ(f(n)),该算法在最坏情况下所需的计算时间为Ω(f(n)). 分析与解答:

计算机算法设计与分析习题及答案

计算机算法设计与分析习 题及答案 Prepared on 24 November 2020

《计算机算法设计与分析》习题及答案 一.选择题 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。随机数函数 D.搜索函数 19. (D)是贪心算法与动态规划算法的共同点。

算法设计与分析期末试题答案解析

1、用计算机求解问题的步骤: 1、问题分析 2、数学模型建立 3、算法设计与选择 4、算法指标 5、算法分析 6、算法实现 7、程序调试 8、结果整理文档编制 2、算法定义:算法是指在解决问题时,按照某种机械步骤一定可以得到问题结果的处理过程 3、算法的三要素 1、操作 2、控制结构 3、数据结构 算法具有以下5个属性: 有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。 确定性:算法中每一条指令必须有确切的含义。不存在二义性。只有一个入口和一个出口 可行性:一个算法是可行的就是算法描述的操作是可以通过已经实现的基本运算执行有限次来实现的。 输入:一个算法有零个或多个输入,这些输入取自于某个特定对象的集合。 输出:一个算法有一个或多个输出,这些输出同输入有着某些特定关系的量。 算法设计的质量指标: 正确性:算法应满足具体问题的需求; 可读性:算法应该好读,以有利于读者对程序的理解;

健壮性:算法应具有容错处理,当输入为非法数据时,算法应对其作出反应,而不是产生莫名其妙的输出结果。 效率与存储量需求:效率指的是算法执行的时间;存储量需求指算法执行过程中所需要的最大存储空间。一般这两者与问题的规模有关。 经常采用的算法主要有迭代法、分而治之法、贪婪法、动态规划法、回溯法、分支限界法 迭代法 基本思想:迭代法也称“辗转法”,是一种不断用变量的旧值递推出新值的解决问题的方法。 解题步骤:1、确定迭代模型。根据问题描述,分析得出前一个(或几个)值与其下一个值的迭代关系数学模型。 2、建立迭代关系式。迭代关系式就是一个直接或间接地不断由旧值递推出新值的表达式,存储新值的变量称为迭代变量 3、对迭代过程进行控制。确定在什么时候结束迭代过程,这是编写迭代程序必须考虑的问题。不能让迭代过程无休止地重复执行下去。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定。对于前一种情况,可以构建一

《算法设计与分析实用教程》习题参考解答

《算法设计与分析实用教程》参考解答 1-1 加减得1的数学游戏 西西很喜欢数字游戏,今天他看到两个数,就想能否通过简单的加减,使最终答案等于1。而他又比较厌烦计算,所以他还想知道最少经过多少次才能得到1。 例如,给出16,9:16-9+16-9+16-9-9-9+16-9-9=1,需要做10次加减法计算。 设计算法,输入两个不同的正整数,输出得到1的最少计算次数。(如果无法得到1,则输出-1)。 (1)若输入两个不同的正整数a,b均为偶数,显然不可能得到1。 设x*a与y*b之差为“1”或“-1”,则对于正整数a,b经n=x+y-1次加减可得到1。 为了求n的最小值,令n从1开始递增,x在1——n中取值,y=n+1-x: 检测d=x*a+y*b,若d=1或-1,则n=x+y-1为所求的最少次数。 (2)算法描述 // 两数若干次加减结果为1的数学游戏 #include void main() {long a,b,d,n,x,y; printf(" 请输入整数a,b: "); scanf("%ld,%ld",&a,&b); if(a%2==0 && b%2==0) { printf(" -1\n");return;} n=0; while(1) { n++; for(x=1;x<=n;x++) { y=n+1-x;d=x*a-y*b; if(d==1 || d==-1) // 满足加减结果为1 { printf(" n=%ld\n",n);return;} } } } 请输入整数a,b: 2012,19 961 请输入整数a,b: 101,2013 606

算法设计与分析试卷及答案.doc

湖南科技学院二○ 年 学期期末考试 信息与计算科学专业 年级《算法设计与分析》 试题 考试类型:开卷 试卷类型: C 卷 考试时量: 120 分钟 题号 一 二 三 四 五 总分 统分人 得 分 阅卷人 一、填空题(每小题 3 分,共计 30 分) 1. 用 O 、Ω和θ表示函数 f 与 g 之间的关系 ______________________________ 。 f n n lo g n g n log n 1, n 1 2. 算法的时间复杂性为 f (n) n ,则算法的时间复杂性的阶 8 f (3n / 7) n, 2 为__________________________ 。 3. 快速排序算法的性能取决于 ______________________________ 。 4. 算法是 _______________________________________________________ 。 5. 在对问题的解空间树进行搜索的方法中,一个活结点最多有一次机会成为活结点的 是_________________________ 。 6. 在算法的三种情况下的复杂性中, 可操作性最好且最有实际价值的是 _____情况下的时间复杂性。 7. 大Ω符号用来描述增长率的下限,这个下限的阶越 ___________,结果就越有价值。 。 8. ____________________________ 是问题能用动态规划算法求解的前提。 9. 贪心选择性质是指 ________________________________________________________ ____________________________________________________________ 。

算法设计与分析复习题目及答案doc

分治法 1、二分搜索算法是利用(分治策略)实现的算法。 9. 实现循环赛日程表利用的算法是(分治策略) 27、Strassen矩阵乘法是利用(分治策略)实现的算法。 34.实现合并排序利用的算法是(分治策略)。 实现大整数的乘法是利用的算法(分治策略)。 17.实现棋盘覆盖算法利用的算法是(分治法)。 29、使用分治法求解不需要满足的条件是(子问题必须是一样的)。 不可以使用分治法求解的是(0/1背包问题)。 动态规划 下列不是动态规划算法基本步骤的是(构造最优解) 下列是动态规划算法基本要素的是(子问题重叠性质)。 下列算法中通常以自底向上的方式求解最优解的是(动态规划法) 备忘录方法是那种算法的变形。(动态规划法) 最长公共子序列算法利用的算法是(动态规划法)。 矩阵连乘问题的算法可由(动态规划算法B)设计实现。 实现最大子段和利用的算法是(动态规划法)。 贪心算法 能解决的问题:单源最短路径问题,最小花费生成树问题,背包问题,活动安排问题, 不能解决的问题:N皇后问题,0/1背包问题 是贪心算法的基本要素的是(贪心选择性质和最优子结构性质)。 回溯法 回溯法解旅行售货员问题时的解空间树是(排列树)。 剪枝函数是回溯法中为避免无效搜索采取的策略 回溯法的效率不依赖于下列哪些因素(确定解空间的时间)

分支限界法 最大效益优先是(分支界限法)的一搜索方式。 分支限界法解最大团问题时,活结点表的组织形式是(最大堆)。 分支限界法解旅行售货员问题时,活结点表的组织形式是(最小堆) 优先队列式分支限界法选取扩展结点的原则是(结点的优先级) 在对问题的解空间树进行搜索的方法中,一个活结点最多有一次机会成为活结点的是( 分支限界法 ). 从活结点表中选择下一个扩展结点的不同方式将导致不同的分支限界法,以下除( 栈式分支限界法 )之外都是最常见的方式. (1)队列式(FIFO)分支限界法:按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。 (2)优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。 (最优子结构性质)是贪心算法与动态规划算法的共同点。 贪心算法与动态规划算法的主要区别是(贪心选择性质)。 回溯算法和分支限界法的问题的解空间树不会是( 无序树 ). 14.哈弗曼编码的贪心算法所需的计算时间为( B )。 A、O(n2n) B、O(nlogn) C、O(2n) D、O(n) 21、下面关于NP问题说法正确的是(B ) A NP问题都是不可能解决的问题 B P类问题包含在NP类问题中 C NP完全问题是P类问题的子集 D NP类问题包含在P类问题中 40、背包问题的贪心算法所需的计算时间为( B )

算法设计与分析(期末总复习)

复习 一、简答题(每小题5分,选答2题,共10分) 1. 什么是算法试说明算法设计分析过程的一般框架和主要步骤。 2. 简述非递归算法时间效率分析的通用方案。 3. 简述递归算法时间效率的通用方案。 4. 简述蛮力法、分治法、减治法,变治法、时空权衡、动态规划、贪婪技术、迭代改进八种算法设计技术中至少三种技术基本思想或原理。 二、分析题(每小题10分,共20分) 1. 考虑下面的算法。P52 算法 Mystery(n) 考虑下面的递归算法。P52 算法 Secret(A[0..n-1]) n-1] minval A[0]; maxval A[0] for i 1 to n-1 do if A[i] < minval minval A[i] if A[i] > maxval maxval A[i] return maxval – minval a.该算法求的是什么 b.它的基本操作是什么 c.该基本操作执行了多少次 d.该算法的效率类型是什么 3. 考虑下面的递归算法P59 算法 Q(n) 建立该函数值的递推关系并求解,以确定该算法计算的是什么; b. 建立该算法所做的乘法运算次数的递推关系并求解; c. 建立该算法所做的加减运算次数的递推关系并求解。

三、算法设计题(每小题10分,共20分) 1. 应用快速排序对序列E,X,A,M,P,L,E按照字母顺序排序。并画出相应的递归调用树。(4章分治法)P102 2. 对于下面的有向图,应用基于DFS的算法来解拓扑排序问题。(5章减治法)P13 3.

3. 用自底向上算法为列表1, 8, 6, 5, 3, 7, 4进行堆排序。(6章变治法)P175 4. 应用Horspool算法在下面的文本中查找模式BARBER:BSS_KNER_BARBER (7章时空权衡)P201

算法设计与分析习题答案

算法设计与分析习题答案(第二版) 主编:吕国英 习题答案 习题答案 第三章: 1. #include #include int main(int argc,char **argv) { int n; int i,j,k; int *buf; printf("请输入n的数值:"); scanf("%d",&n); buf=(int *)malloc(n*sizeof(int)); for(i=0;i=0;i--)

for(j=i;j>=0;j--) { buf[j]+=2; } } for(k=0;k<=n-2;k++) { if(buf[k]>=10) { buf[k+1]+=buf[k]/10; buf[k]%=10; } } for(i=n-1;i>=0;i--) printf("%d",buf[i]); printf("\n"); return 0; } 2. #include int main(int argc,char **argv)

int buf[6][6]; int i,j; printf("任意输入6个数字:"); for(i=0;i<6;i++) scanf("%d",&buf[0][i]); for(i=0;i<5;i++) { for(j=0;j<5;j++) { buf[i+1][j+1]=buf[i][j]; } buf[i+1][0]=buf[i][j]; } for(i=0;i<6;i++) { for(j=0;j<6;j++) printf("%d ",buf[i][j]); printf("\n"); } return 0; }

相关文档
最新文档