high←mid-1
:
x>A(mid):
low←mid+1
:
else:
j←mid;return
endcase
repeat
j←0
endBINSRCH
解:
logn+1
三、算法理解
1、写出多段图最短路经动态规划算法求解下列实例的过程,并求出最优值。
各边的代价如下:
C(1,2)=3,C(1,3)=5,C(1,4)=2
C(2,6)=8,C(2,7)=4,C(3,5)=5,C(3,6)=4,C(4,5)=2,C(4,6)=1
C(5,8)=4,C(6,8)=5,C(7,8)=6
解:
Cost(4,8)=0
Cost(3,7)=C(7,8)+0=6,D[5]=8
Cost(3,6)=C(6,8)+0=5,D[6]=8
Cost(3,5)=C(5,8)+0=4D[7]=8
Cost(2,4)=min{C(4,6)+Cost(3,6),C(4,5)+Cost(3,5)}
=min{1+5,2+4}=6D[4]=6
Cost(2,3)=min{C(3,6)+Cost(3,6)}
=min{4+5}=9D[3]=5
Cost(2,2)=min{C(2,6)+Cost(3,6),C(2,7)+Cost(3,7)}
=min{8+5,4+6}=10D[2]=7
Cost(1,1)=min{C(1,2)+Cost(2,2),C(1,3)+Cost(2,3),C(1,4)+Cost(2,4)}
=min{3+10,5+9,2+6}=8
D[1]=4
1→4→6→8
2、写出maxmin算法对下列实例中找最大数和最小数的过程。
数组A=(48,12,61,3,5,19,32,7)
解:
写出maxmin算法对下列实例中找最大数和最小数的过程。
数组A=()
1、48,12,61,3,5,19,32,7
2、48,1261,35,1932,7
3、48~61,12~319~32,5~7
4、61~323~5
5、613
1、快速排序算法对下列实例排序,算法执行过程中,写出数组A第一次被分割的过程。
A=(65,70,75,80,85,55,50,2)
解:
第一个分割元素为65
2、归并排序算法对下列实例排序,写出算法执行过程。
A=(48,12,61,3,5,19,32,7)
解:
48,12,61,35,19,32,7
48,1261,35,1932,7
12,483,615,197,32
3,12,48,615,7,19,32
3,5,7,12,19,32,48,61
3、写出图着色问题的回溯算法的判断X[k]是否合理的过程。
解:
i←0
whileiifG[k,i]=1andX[k]=X[i]then
returnfalse
i←i+1
repeat
ifi=kthenreturntrue
4、对于下图,写出图着色算法得出一种着色方案的过程。
解:
K←1
X[1]←1,返回true
X[2]←1,返回false;X[2]←X[2]+1=2,返回true
X[3]←1,返回false;X[3]←X[3]+1=2,返回false;X[3]←X[3]+1=3,返回true
X[4]←1,返回false;X[4]←X[4]+1=2,返回false;X[4]←X[4]+1=3,返回true
找到一个解(1,2,3,3)
5、写出第7题的状态空间树。
解:
8、写出归并排序算法对下列实例排序的过程。
(6,2,9,3,5,1,8,7)
解:
调用第一层次6,2,9,35,1,8,7分成两个子问题
调用第二层次6,29,35,18,7分成四个子问题
调用第三层次62935187分成八个子问题
调用第四层次只有一个元素返回上一层
第三层归并2,63,91,57,8返回上一层
第二层归并2,3,6,91,5,7,8返回上一层
第一层归并1,2,3,5,6,7,8,9排序结束,返回主函数
9、写出用背包问题贪心算法解决下列实例的过程。
P=(18,12,4,1)
W=(12,10,8,3)
M=25
解:
实例符合P(i)/W(i)≥P(i+1)/W(i+1)的顺序。
CU←25,X←0
W[1]x[1]←1;CU←CU-W[1]=13;
W[2]x[2]←1;CU←CU-W[2]=3;
W[3]>CU:
x[3]←CU/W[3]=3/8;
实例的解为:
(1,1,3/8,0)
11、有一个有序表为{1,3,9,12,32,41,45,62,75,77,82,95,100},当使用二分查找值为82的结点时,经过多少次比较后查找成功并给出过程。
解:
有一个有序表为{1,3,9,12,32,41,45,62,75,77,82,95,100},当使用二分查找值为82的结点时,经过多少次比较后查找成功并给出过程。
一共要要执行四次才能找到值为82的数。
12、使用prim算法构造出如下图G的一棵最小生成树。
dist(1,2)=6;dist(2,5)=3;dist(5,6)=6;dist(6,4)=2;dist(4,1)=5;
dist(1,3)=1;dist(2,3)=5;dist(3,4)=5;dist(3,6)=4;dist(5,3)=6
解:
使用普里姆算法构造出如下图G的一棵最小生成树。
dist(1,2)=6;dist(2,5)=3;dist(5,6)=6;dist(6,4)=2;dist(4,1)=5;
dist(1,3)=1;dist(2,3)=5;dist(3,4)=5;dist(3,6)=4;dist(5,3)=6
13、有如下函数说明
intf(intx,inty)
{
f=xMody+1;
}
已知a=10,b=4,c=5则执行k=f(f(a+c,b),f(b,c))后,k的值是多少并写出详细过程。
解:
有如下函数说明
intf(intx,inty)
{
f=xMody+1;
}
已知a=10,b=4,c=5则执行k=f(f(a+c,b),f(b,c))后,k的值是多少并写出详细过程。
}
K的值是5
14、McCathy函数定义如下:
当x>100时m(x)=x-10;
当x<=100时m(x)=m(m(x+11));
编写一个递归函数计算给定x的m(x)值。
解:
McCathy函数定义如下:
当x>100时m(x)=x-10;
当x<=100时m(x)=m(m(x+11));
编写一个递归函数计算给定x的m(x)值。
intm(intx)
{
inty;
if(x>100)return(x-100);
else
{
y=m(x+11);
return(m(y));
}
}
15、设计一个算法在一个向量A中找出最大数和最小数的元素。
解:
设计一个算法在一个向量A中找出最大数和最小数的元素。
Voidmaxmin(A,n)
VectorA;
intn;
{
intmax,min,i;
max=A[1];min=A[1];
for(i=2;i<=n;i++)
if(A[i]>max)max=A[i];
elseif(A[i]printf(“max=%d,min=%d\n”,max,min);
}
四、设计算法
1.设有n项独立的作业{1,2,…,n},由m台相同的机器加工处理。
作业i所需要的处理时间为ti。
约定:
任何一项作业可在任何一台机器上处理,但未完工前不准中断处理;任何作业不能拆分更小的子作业。
多机调度问题要求给出一种调度方案,使所给的n个作业在尽可能短的时间内由m台机器处理完。
设计算法,并讨论是否可获最优解。
解:
对于处理机j,用S[j]表示处理机j已有的作业数,用P[j,k]表示处理机j的第k个作业的序号。
1)将作业按照t[1]≥t[2]≥……≥t[n]排序
2)S[1:
m]清零j←0设有n种面值为:
d1≥d2≥……≥dn的钱币,需要找零钱M,如何选择钱币dk,的数目Xk,满足
d1×Xi+……dn×XnM,使得
Xi+……Xn最小
请选择贪心策略,并设计贪心算法。
解:
贪心原则:
每次选择最大面值硬币。
CU←M;i←1;X←0有n个物品,已知n=7,利润为P=(10,5,15,7,6,18,3),重量W=(2,3,5,7,1,4,1),背包容积M=15,物品只能选择全部装入背包或不装入背包,设计贪心算法,并讨论是否可获最优解。
解:
定义结构体数组G,将物品编号、利润、重量作为一个结构体:
例如G[k]={1,10,2}
求最优解,按利润/重量的递减序,有
{5,6,1,6}{1,10,2,5}{6,18,4,9/2}{3,15,5,3}{7,3,1,3}{2,5,3,5/3}{4,7,7,1}
算法
procedureKNAPSACK(P,W,M,X,n)
设计只求一个哈密顿环的回溯算法。
解:
Hamiltonian(n)
{k←1;x[k]←0;
Whilek>0do
x[k]←x[k]+1;
whileB(k)=falseandx[k]≤ndo
x[k]←x[k]+1;repeat
Ifx[k]≤nthen
ifk=nthen{printx;return}
else{k←k+1;x[k]←0;}endif
elsek←k-1
endif
repeat
end
procedureB(k)
{G[x[k-1],x[k]]≠1thenreturnfalse;
fori←1tok-1do
ifx[i]=x[k]thenreturnfalse;endif
repeat
returntrue;
}
5.利用对称性设计算法,求n为偶数的皇后问题所有解。
解:
利用对称性设计算法,求n为偶数的皇后问题所有解。
procedureNQUEENS1(n)
a←0
(4分)
cout<}
elsefor(inti=k;i<=m;i++)
if(ok(list,k,i)){
swap(list[k],list[i]);
Perm(list,k+1,m);
swap(list[k],list[i]);……………………………..(8分)
};
}
其中ok用于判别重复元素。
Template
intok(Typelist[],intk,inti)
{
if(i>k)
for(intt=k;t
if(list[t]==list[i])return0;
return1;
}……………………………..(13分)
3、试用分治法对一个有序表实现二分搜索算法。
(12分)
解:
解答如下:
Template
intBinarySearch(Typea[],constType&x,intn)
{(4分)
if(x==a[middle])returnmiddle+1;
if(x>a[middle])left=middle+1;……………………………..(8分)
elseright=middle-1;
}
return-1;
}……………………………..(12分)
4、试用动态规划算法实现0-1闭包问题。
(15分)
解:
解答如下:
Template
voidKnapsack(Typev,intw,intc,intn,Type**m)
{
IntjMax=min(w[n]-1,c);
for(intj=0;j<=jMax;j++)m[n][j]=0;
for(intj=w[n];j<=c;j++)m[n][j]=v[n];……………………………..(5分)
for(inti=n-1;i>1;i--){
jMax=min(w[i]-1,c);
for(intj=0;j<=jMax;j++)m[i][j]=m[i+1][j];
for(intj=w[i];j<=c;j++)m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);…………..(8分)
};
m[1][c]=m[2][c];
if(c>=w[1])m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]);…………..(10分)
}
Template
VoidTraceback(Type**m,intw,intc,intn,intx)
{
for(inti=1;iif(m[i][c]==m[i+1][c])x[i]=0;…………..(12分)
else{x[i]=1,c-=w[i];};
x[n]=(m[n][c])1:
0;
}……………………………..(15分)
5、试用贪心算法求解下列问题:
将正整数n分解为若干个互不相同的自然数之和,使这些自然数的乘积最大。
(15分)
解:
解答如下:
voiddicomp(intn,inta[])
{
k=1;
if(n<3){a[1]=0;return;};
if(n<5){a[k]=1;a[++k]=n-1;return;};……………………………..(5分)
a[1]=2;n-=2;
while(n>a[k]){
k++;
a[k