一.单选题(共30题,42.0分)
1算法是由若干条指令组成的有穷序列,而且满足以下性质( )
(1)输入:有0个或多个输入 (2)输出:至少有一个输出
(3)确定性:指令清晰,无歧义 (4)有限性:指令执行次数有限,而且执行时间有限
A、(1)(2)(3)
B、(1)(2)(4)
C、(1)(3)(4)
D、(1)(2)(3)(4)
正确答案: D 我的答案:D
2算法分析中,记号O表示( ),记号表示( ),记号表示( )。
1.渐进下界; 2.渐进上界; 3.非紧上界; 4.紧渐进界; 5.非紧下界;
A、1,2,4
B、2,1,4
C、5,3,4
D、3,5,4
正确答案: B 我的答案:B
3回溯法搜索状态空间树是按照( )的顺序。
A、中序遍历
B、广度优先遍历
C、深度优先遍历
D、层次优先遍历
正确答案: C 我的答案:C
4实现最大子段和利用的算法是( )。
A、分治策略
B、动态规划法
C、贪心法
D、回溯法
正确答案: B 我的答案:B
5解决活动安排问题,最好用( )算法
A、分治
B、贪心
C、动态规划
D、穷举
正确答案: B 我的答案:B
6用动态规划算法解决最大字段和问题,其时间复杂性为( )。
A、logn
B、n
C、n2
D、nlogn
正确答案: B 我的答案:B
7下列算法中通常以自底向上的方式求解最优解的是( )。
A、分治法
B、动态规划法
C、贪心法
D、回溯法
正确答案: B 我的答案:B
8应用Johnson法则的流水作业调度采用的算法是( )
A、贪心算法
B、分支限界法
C、分治法
D、动态规划算法
正确答案: A我的答案:A
9以深度优先方式系统搜索问题解的算法称为( )。
A、分支界限算法
B、概率算法
C、贪心算法
D、回溯算法
正确答案: D 我的答案:D
10备忘录方法是那种算法的变形。( )
A、分治法
B、动态规划法
C、贪心法
D、回溯法
正确答案: B 我的答案:B
11背包问题的贪心算法所需的计算时间为( )。
A、O(n2)
B、O(nlogn)
C、O(2)
D、O(n)
正确答案: B 我的答案:B
12二分搜索算法是利用( )实现的算法。
A、分治策略
B、动态规划法
C、贪心法
D、回溯法
正确答案: A 我的答案:A
13实现棋盘覆盖算法利用的算法是( )。
A、分治法
B、动态规划法
C、贪心法
D、回溯法
正确答案: A 我的答案:A
14合并排序算法是利用( )实现的算法。
A、分治策略
B、动态规划法
C、贪心法
D、回溯法
正确答案: A 我的答案:A
15贪心算法与动态规划算法的主要区别是( )。
A、最优子结构
B、贪心选择性质
C、构造最优解
D、定义最优解
正确答案: B 我的答案:B
16能采用贪心算法求最优解的问题,一般具有的重要性质为:( )
A、最优子结构性质与贪心选择性质
B、重叠子问题性质与贪心选择性质
C、最优子结构性质与重叠子问题性质
D、预排序与递归调用
正确答案: A 我的答案:A
17实现大整数的乘法是利用的算法( )。
A、贪心法
B、动态规划法
C、分治策略
D、回溯法
正确答案: C 我的答案:C
18实现合并排序利用的算法是( )。
A、分治策略
B、动态规划法
C、贪心法
D、回溯法
正确答案: A 我的答案:A
19下面问题( )不能使用贪心法解决。
A、单源最短路径问题
B、N皇后问题
C、最小生成树问题
D、部分背包问题
正确答案: B 我的答案:B
20最长公共子序列算法利用的算法是( )。
A、分支界限法
B、动态规划法
C、贪心法
D、回溯法
正确答案: B 我的答案:B
21 0-1背包问题的回溯算法所需的计算时间为( )
A、O(n2n)
B、O(nlogn)
C、O(2n)
D、O(n)
正确答案: C 我的答案:C
22下列是动态规划算法基本要素的是( )。
A、定义最优解
B、构造最优解
C、算出最优解
D、子问题重叠性质
正确答案: D 我的答案:D
23函数3*2n+10*n*logn的渐进表达式是( )。
A、2n
B、3*2n
C、n*logn
D、10*n*logn
正确答案: B 我的答案:A
24( )是贪心算法与动态规划算法的共同点。
A、重叠子问题
B、构造最优解
C、贪心选择性质
D、最优子结构性质
正确答案: D 我的答案:D
25矩阵连乘问题的算法可由( )设计实现。
A、分支界限算法
B、动态规划算法
C、贪心算法
D、回溯算法
正确答案: B 我的答案:B
26采用贪心算法的最优装载问题的主要计算量在于将集装箱依其重量从小到大排序,故算法的时间复杂度为( )。
A、O(n2n)
B、O(nlogn)
C、O(2n)
D、O(n)
正确答案: B 我的答案:B
27采用广度优先策略搜索的算法是( )。
A、分支界限法
B、动态规划法
C、贪心法
D、回溯法
正确答案: A 我的答案:A
28下面哪种函数是回溯法中为避免无效搜索采取的策略( )。
A、递归函数
B、剪枝函数
C、随机数函数
D、搜索函数
正确答案: B 我的答案:B
29回溯法解旅行售货员问题时的解空间树是( )。
A、子集树
B、排列树
C、深度优先生成树
D、广度优先生成树
正确答案: B 我的答案:B
30使用分治法求解不需要满足的条件是( )。
A、子问题必须是一样的
B、子问题不能够重复
C、子问题的解可以合并
D、原问题和子问题使用相同的方法解
正确答案: A 我的答案:A
二.填空题(共25题,35.0分)
1快速排序算法的性能取决于____。
第一空:
划分的对称性
2回溯法搜索解空间树时,常用的两种剪枝函数为____ 和 ____ 。
第一空:
约束函数
第二空:
限界函数
3使用回溯法进行状态空间树裁剪分支时一般有两个标准:____和____,N皇后问题和0/1背包问题正好是两种不同的类型,其中同时使用约束条件和目标函数的界进行裁剪的是____,只使用约束条件进行裁剪的是____。
第一空:
约束条件
第二空:
目标函数的界
第三空:
0/1背包问题
第四空:
N皇后问题
4贪心法求解活动安排问题
bool flag[MAX]; //标记选择的活动
int cnt; //选取的兼容活动个数
int n; //可选择的活动个数
struct Action{ //活动的类型声明
int b; //活动起始时间
int e; //活动结束时间
bool operator<(const Action &s) const {//重载<关系函数
return____;//用于按活动结束时间递增排序
}
} A[MAX];
void solve(){ //求解最大兼容活动子集
memset(flag,0,sizeof(flag)); //初始化为false
sort(A+1,A+n+1); //A[1..n]按活动结束时间递增排序
int preend=0; //前一个兼容活动的结束时间
for (int i=1;i<=n;i++){ //扫描所有活动
if (____) { //找到一个兼容活动
flag[i]=true; //选择A[i]活动
____;//更新preend值
cnt++;
}
}
}
第一空:
e<=s.e
第二空:
A[i].b>=preend
第三空:
preend=A[i].e
5解决0/1背包问题可以使用动态规划、回溯法和分支限界法,其中不需要排序的是____,需要排序的是____,____。
第一空:
动态规划
第二空:
回溯法
第三空:
分支限界法
6回溯法是一种既带有____又带有____的搜索算法。
第一空:
系统性
第二空:
跳跃性
7从分治法的一般设计模式可以看出,用它设计出的程序一般是____
第一空:
递归算法 。
8矩阵连乘问题的算法可由____设计实现。
第一空:
动态规划
9从分治法的一般设计模式可以看出,用它设计出的程序一般是____ 。
第一空:
递归算法
10动态规划算法的两个基本要素是.____和____性质
第一空:
最优子结构性质
第二空:
重叠子问题
11算法的复杂性有____和 空间____。
第一空:
时间 复杂性
第二空:
复杂性之分
12动态规划求解两字符串的最长公共子序列的长度
char x[MAXN],y[MAXN];//两字符串
int m, n; //两字符串的长度
int c[MAXN][MAXN]; //c[i][j]:长度为i的串与长度为j的串的最长公共子序列的长度
int LCSLength() {
int i, j;
for(i = 0; i <= m; i++) ____;
for(j = 1; j <= n; j++)____;
for(i = 1; i<= m; i++) {
for(j = 1; j <= n; j++) {
if(x[i-1] == y[j-1]) {
____;
}
else if(c[i-1][j] >= c[i][j-1]) {
____;
}
else {
____;
}
}
}
return c[m][n];
}
第一空:
c[i][0] = 0
第二空:
c[0][j] = 0
第三空:
c[i][j] = c[i-1][j-1] + 1
第四空:
c[i][j] = c[i-1][j]
第五空:
c[i][j] = c[i][j-1]
13回溯法求解流水作业调度问题
void dfs(int i) { //从第i层开始搜索
if (i>n) { //到达叶子结点,产生一种调度方案
if (t2[n]<bestf){ //找到更优解
bestf=t2[n];
for(int j=1; j<=n; j++)
bestx[j] = x[j]; //复制解向量
}
return;
}else{
for(int j=i; j<=n; j++){ //没有到达叶子结点,考虑i到n的作业
t1 =____;//在第i层选择执行作业x[j],在M1上执行完的时间
t2[i]=____;
if (t2[i]<bestf) {//剪枝:仅仅扩展当前总时间小于bestf的结点
____;
____;
____;
}
t1 -= a[x[j]];//回溯,撤销第i层对作业x[j]的选择,以便再选择其他作业
}
}
}
第一空:
t1 + a[x[j]]
第二空:
max(t1,t2[i-1])+b[x[j]]
第三空:
swap(x[i],x[j])
第四空:
dfs(i+1)
第五空:
swap(x[i],x[j])
14图的m着色问题可用____ 法求解,其解空间树中叶子结点个数是____,解空间树中每个内结点的孩子数是____。
正确答案:
第一空:
回溯
第二空:
mn
第三空:
m
15回溯法是一种既带有 ____ 又带有 ____ 的搜索算法。
第一空:
系统性
第二空:
跳跃性
16贪心算法的基本要素是____性质和____性质 。
第一空:
贪心选择
第二空:
最优子结构
17合并排序描述如下:
void Mergesort(int a[ ], int left, int right){
if (____){
int i=(____)/2;
Mergesort(a, left, i );
Mergesort(____);
Merge(a,b, left,i,right);//合并到数组b
Copy(a,b, left,right); //复制到数组a
}
}
第一空:
left<right
第二空:
left+right
第三空:
a,i+1,right
18贪心法求解田忌赛马问题
int n;//双方的马匹数量
int a[MAX]; //田忌的马
int b[MAX]; //齐威王的马
int ans; //求解结果表示
void solve(){ //求解算法
sort(a,a+n); //对a递增排序
sort(b,b+n); //对b递增排序
ans=0;
int lefta=0,leftb=0;
int righta=n-1,rightb=n-1;
while (lefta<=righta) { //比赛直到结束
if (____){//田忌最快的马比齐威王最快的马快,两者比赛
ans+=200;
____;
____;
}else if (____){ //田忌最快的马比齐威王最快的马慢
ans-=200;
//选择田忌最慢的马与比齐威王最快的马比赛
____;
rightb--;
} else{ //田忌最快的马与齐威王最快的马的速度相同
if (____) {//田忌最慢的马比齐威王最慢的马快,两者比赛
ans+=200;
lefta++;
leftb++;
} else if (____) {//否则,用田忌最慢的马与齐威王最快的马比赛
ans-=200;
____;
rightb--;
}
}
}
}
第一空:
a[righta]>b[rightb]
第二空:
righta--
第三空:
rightb--
第四空:
a[righta]<b[rightb]
第五空:
lefta++
第六空:
a[lefta]>b[leftb]
第七空:
a[lefta]<b[rightb]
第八空:
lefta++
19动态规划算法的基本思想是将待求解问题分解成若干____,先求解 ____ ,然后从这些____ 的解得到原问题的解。
第一空:
子问题
第二空:
子问题
第三空:
子问题
20问题的____是该问题可用动态规划算法或贪心算法求解的关键特征。
第一空:
最优子结构性质
21回溯法搜索解空间树时,常用的两种剪枝函数为____和____
第一空:
约束函数
第二空:
限界函数
22
使用回溯法进行状态空间树裁剪分支时一般有两个标准:约束条件和目标函数的界,N皇后问题和0/1背包问题正好是两种不同的类型,其中同时使用约束条件和目标函数的界进行裁剪的是 ____ ,只使用约束条件进行裁剪的是____ 。
第一空:
0/1背包问题
第二空:
N皇后问题
23贪心算法的基本要素是____质和 ____性质 。
第一空:
贪心选择
第二空:
最优子结构
24动态规划算法的两个基本要素是: ____ 性质和 ____ 性质 。
第一空:
最优子结构
第二空:
重叠子问题
25动态规划算法的基本思想是将待求解问题分解成若干____,先求解 ____,然后从这些____的解得到原问题的解。
第一空:
子问题
第二空:
子问题
第三空:
子问题
三.判断题(共10题,14.0分)
1深度优先搜索算法可以搜索到问题所有可能的解方案。
正确答案:×
2最优子结构性质是指原问题的最优解包含其子问题的最优解。
正确答案:√
3动态规划算法基本要素的是最优子结构。
正确答案:√
4好的算法在很大程度上取决于问题中数据所采用的数据结构。
正确答案:√
5满足贪心选择性质必满足最优子结构性质。
正确答案:×
6动态规划算法求解问题时,分解出来的子问题相互独立。
正确答案:×
7适用动态规划算法解决问题应该具有最优化原理和子问题重叠。
正确答案:×
8用贪婪算法解决零钱兑换问题时,总能找到问题的最优解。
正确答案:×
9回溯法中限界函数的目的是剪去得不到最优解的子树。
正确答案:√
10解决马的遍历问题采用回溯法,对解空间树的搜索采用广度优先搜索方式
正确答案:√
四.简答题(共6题,9.0分)
1如下图所示的一个数塔,从顶部出发,在每一结点可以选择向左走或是向右走,一直走到底层,要求找出一条路径,使路径上的数值和最大。
正确答案:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXV 10005
int a[MAXV][MAXV];//数塔中的元素
int dp[MAXV][MAXV];//dp[i][j]为(i,j)到底部的最大路径和
int n;//数塔的行数
int Search() {
int i,j;
for(j=0; j<n; j++) { //边界条件
dp[n-1][j]=a[n-1][j];
}
for (i=n-2; i>=0; i--) {
for (j=0; j<=i; j++) {
dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];
}
}
return dp[0][0];
}
int main() {
memset(dp,0,sizeof(dp));
scanf("%d",&n); //输入三角形的高度
for (int i=0; i<n; i++) { //输入三角形
for (int j=0; j<=i; j++) {
scanf("%d",&a[i][j]);
}
}
printf("%d\n",Search()); //输出最大路径和
return 0;
}
2试用分治法对一个有序表实现二分搜索算法。
正确答案:
int BinarySearch(int a[],const int& x,int n) {
//假定数组a[]已按非递减有序排列,本算法找到x后返回其在数组a[]
//中的位置,否则返回-1
int left=0,right=n-1;
while(left<=right){
int middle=(left+right)/2; ……………………………..(4分)
if(x= =a[middle]) return middle+1;
if(x>a[middle]) left=middle+1; ……………………………..(8分)
else right=middle-1;
}
return -1;
}……………………………..(12分)
3写出图的m着色问题的回溯算法
正确答案:
int n,m; //顶点数,m色
int x[MAXV]; //着色方案
int a[MAXV][MAXV]; //邻接表
bool Same(int i) { //判断顶点i是否与相邻顶点存在相同的着色
for (int j=1; j<=n; j++)
if (a[i][j]==1 && x[i]==x[j])
return false;
return true;
}
void dfs(int i) { //求解图的m着色问题
if (i>n) //达到叶子结点
count++; //着色方案数增1
else {
for (int j=1; j<=m; j++) { //试探每一种着色
x[i]=j; //试探着色j
if (Same(i)) //可以着色j,进入下一个顶点着色
dfs(i+1);
x[i]=0; //回溯
}
}
}
4简单描述回溯法基本思想。
正确答案:
回溯法的基本思想是在一棵含有问题全部可能解的状态空间树上进行深度优先搜索,解为叶子结点。搜索过程中,每到达一个结点时,则判断该结点为根的子树是否含有问题的解,如果可以确定该子树中不含有问题的解,则放弃对该子树的搜索,退回到上层父结点,继续下一步深度优先搜索过程。在回溯法中,并不是先构造出整棵状态空间树,再进行搜索,而是在搜索过程,逐步构造出状态空间树,即边搜索,边构造。
5简单描述分治法的基本思想。
正确答案:
分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同;对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止;将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。
6写出设计动态规划算法的主要步骤。
正确答案:
设计一个标准的动态规划算法,通常可按以下几个步骤进行:
1)划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。
2)选择状态:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。
3)写出状态转移方程:状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。
4)写出规划方程(包括边界条件):动态规划的基本方程是规划方程的通用形式化表达式。