算法设计与分析b卷及答案

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

算法设计与分析试卷B 与解答
一.填空题:(每题4分,共20分)
1. 算法的特性有 _0至多个输入, 至少一个输出, 指令无歧义性,指令条数有限且每条指令执行时间有限 .
2.直接或间接地调用自身的算法称为 递归 算法。

用函数自身给出定义的函数称为 递归 函数。

3.在回溯法中,为了避免无效的搜索,通常采用两种剪枝策略,分别为
和 。

(约束剪枝,限界剪枝)
4. 算法的时间复杂性T (n ) 是指算法
其中n 是问题的规模。

5.动态规划算法的两大基本要素分别为 和 。

(最优子结构性质和子问题的重叠性质。


二.简答题:(每小题5分,共20分)
1. 给定2个序列12{,,,}m X x x x =L 和12{,,,}n Y y y y =L ,说明X 和Y 的最长公共子序列问题具有最优子结构性质。

设序列X m ={x 1,x 2,…,x m }和Y n ={y 1,y 2,…,y n }的最长公共子序列为Z k ={z 1,z 2,…,z k
} ,则 (1)若x m =y n ,那么z k =x m =y n ,且Z k-1是X m-1和Y n-1的最长公共子序列。

(2)若x m ≠y n 且z k ≠x m ,那么Z k 是X m-1和Y n
的最长公共子序列。

(3)若x m ≠y n 且z k ≠y n ,那么Z k 是X m 和Y n-1的最长公共子序列。

由此可见,2个序列的最长公共子序列包含了这2个序列的前缀的最长公共子序列。

因此,最长公共子序列问题具有最优子结构性质。

2. 简述常见的两种分支限界法。

(1)队列式(FIFO)分支限界法:按照队列先进先出(FIFO )原则选取下一个节点为扩展节点。

(2)优先队列式分支限界法:按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。

3. 假设以加法和乘法为关键操作,估算下述n 次多项式求值函数的时间复杂度(取T 为整型)
template<class T>
T PolyEval(T coeff[], int n, const T& x)
{ // 计算 n 次多项式的值, coeff[0:n] 为多项式的系数
T y=1, value=coeff[0];
for(i=1;i<=n;i++) {
y*=x;
value+=y*coeff[i];
}
return value;
}
解答:T PolyEval(T coeff[], int n, const T& x)
{ // 计算n 次多项式的值,coeff[0:n]为多项式的系数
T y=1, value=coeff[0];
for(i=1;i<=n;i++) //n 循环{ // 累加下一项
y*=x; //一次乘法
value+=y*coeff[i]; //一次加法和一次乘法
}
return value;
} // 3n 次基本操作
4.动态规划算法的基本思想是什么?它和分治法有什么区别和联系?
答:动态规划算法的基本思想为:该方法的思路也是将待求解的大问题分成规模较小的子问题,但所得的各子问题之间有重复子问题,为了避免子问题的重复计算,可依自底向上的方式计算最优值,并根据子问题的最优值合并得到更大问题的最优值,进而可构造出所求问题的最优解。

分治法也是将待求解的大问题分成若干个规模较小的相同子问题,即该问题具有最优子结构性质。

规模缩小到一定的程度就可以容易地解决。

所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题;利用该问题分解出的子问题的解可以合并为该问题的解。

三.算法分析解答题:(每题20分,共60分)
1. 假设有n(n N且n>1)个硬币,已知其中有一个是假币且假币较真币轻. 请设计分治算法求解该问题.并给出其复杂度分析.
Feit_money(low, high) // 假定伪币较真币轻{
float mid;
if ( high-low==1 )
if (A[low]<A[high]) return A[low];
else if (A[low]>A[high]) return A[high];
else {
mid=(low+high)/2;
if ((high-low+1)%2)==0 {
sum1=sum(low, mid);
sum2=sum(mid+1, high);
}
else{
sum1=sum(low, mid-1);
sum2=sum(mid+1, high);
}
if sum1==sum2 return A[mid];
else if (sum1<sum2)
(high-low+1)%2==0? Feit_money(low, mid) : Feit_money(low, mid-1); else
Feit_money(mid+1, high);
}
return 0;
} //其时间复杂度为:O(log n).
2. 记矩阵连乘积 1[,]...,i i j A i j A A A i j +=≤%。

确定计算A[1:n]的最优计算次序,使得所需数乘的次数最少。

1、说明矩阵连乘计算次序问题的最优解包含着其子问题的最优解,即最优子结构性质。

2、该问题具备子问题的重叠性质。

3、说明采用动态规划方法可以解决该问题。

4、设计该算法,分析算法的复杂性。

解:设这个计算次序在矩阵A k 和A k+1之间将矩阵链断开,i ≤ k<j ,则其相应完全加括号方式为 112(...)(...)i i k k k j A A A A A A +++。

则A[1:n]的数乘次数m[1:n],即计算量,等于A[i:k]的计算量加上A[k+1:j]的计算量,再加上A[i:k]和A[k+1:j]相乘的计算量。


1[,][1,][,]0
i k j m i k m k j p p p i j m i j i j -+++<⎧=⎨=⎩
i A 是1:i i p p -⨯阶矩阵。

1、 所以可以看到计算A[i:j]的最优次序所包含的计算矩阵子链 A[i:k]和A[k+1:j]
的次序也是最优的。

该问题具有最优子结构性质;
2、 递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计
算多次。

这种性质称为子问题的重叠性质。

3、 由于最优子结构性质和子问题的重叠性质,所以该问题可用动态规划算
法求解。

void MatrixChain(int *p ,int n ,int **m ,int **s){
for (int i = 1; i <= n; i++) m[i][i] = 0;
for (int r = 2; r <= n; r++)
for (int i = 1; i <= n - r+1; i++) {
int j=i+r-1;
m[i][j] = m[i+1][j]+ p[i-1]*p[i]*p[j];
s[i][j] = i;
for (int k = i+1; k < j; k++) {
int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if (t < m[i][j]) { m[i][j] = t; s[i][j] = k;}
}
}
}
算法复杂度分析:
算法matrixChain 的主要计算量取决于算法中对r ,i 和k 的3重循环。

循环体内的计算量为O(1),而3重循环的总次数为O(n 3)。

因此算法的计算时间上界为O(n 3)。

算法所占用的空间显然为O(n 2)。

3. 考虑分数背包问题,定义如下:给出n 个大小为 s 1, s 2, …, s n , 价值为v 1, v 2, …, v n 的物品, 并设背包容量为C, 要找到非负实数x 1, x 2, …, x n , 使和 ∑=n i i i v x 1 在约束∑=≤n
i i i C s x 1下最大。

写出求解问题的贪心算法,估计算法的时间复杂性。

float knapsack(float c, float s[], float v[], float x[]) {
int n=v.length;
Element [] d = new Element [n];
for (int i = 0; i < n; i++) d[i] = new Element(s[i], v[i], i);
MergeSort.mergeSort(d);//按物品的单位价值非降序排序
int i; float opt=0;
for (i=0;i<n;i++) x[i]=0;
for (i=0;i<n; i++) {
if (d[i].w>c) break;
x[d[i].i]=1; opt+=d[i].v; c-=d[i].s;
}
if (i<n) { x[d[i].i]=c/d[i].w; opt+=x[d[i].i]*d[i].v; }
return opt;
} // T(n)=O(nlogn),当n 个物品不是按照单位价值非降序排序时,需要对其进行排序。

相关文档
最新文档