1、算法分析考试题1. 给定数组a0:n-1,试设计一个算法,在最坏情况下用n+logn-2次比较找出a0:n-1 中的元素的最大值和次大值. (算法分析与设计习题 2.16 ) (分治法)a、 算法思想用分治法求最大值和次大值首先将问题划分,即将划分成长度相等的两个序列,递归求出左边的最大值次大值,再求出右边的的最大值次大值,比较左右两边,最后得出问题的解。 b、复杂度分析:把问题划分为左右两种的情况,需要分别递归求解,时间复杂度可如下计算:有递推公式为:T(n)=1 n=1 T(n)= 2T(n/2)+1 n1 所以,分治算法的时间复杂度是n+logn-2,当n为奇数时,logn取上线,当n为
2、偶数时,logn取下线。/不知道为什么会-2!C、代码实现:#include int a100;void maxcmax(int i,int j,int &max,int &cmax) int lmax,lcmax,rmax,rcmax; int mid; if (i=j) max=ai; cmax=ai; else if (i=j-1) if (airmax) if(lcmaxrmax) max=lmax; cmax=lcmax; else max=lmax; cmax=rmax; else if(rcmaxlmax) if(rmax=rcmax) max=rmax; cmax=lmax;
3、else max=rmax; cmax=rcmax; else max=rmax; cmax=lmax; int main() int n; int max,cmax; printf(输入数组长度); scanf(%d,&n); printf(输入数组:n); for(int i=0;i1 所以,分治算法的时间复杂度是O(nlogn)c、代码实现#include#define m 10int MaxSubSum(int a,int left,int right) int sum=0; if(left=right) sum=aleft0?aleft:0; else int i=(left+rig
4、ht)/2; int max1=MaxSubSum(a,left,i); int max2=MaxSubSum(a,i+1,right); int sum1=0,sum2=0; for(int j=i;j=left;j-) sum1=sum1+aj; if(sum1sum2) sum2=sum1; int sum3=0,sum4=0; for(j=i+1;jsum4) sum4=sum3; sum=sum2+sum4; if(summax1) sum=max1; if(summax2) sum=max2; return sum; void main() int am,d; cout请输入元素个
5、数d; cout请输入元素endl; for(int i=0;iai; cout最大子段和为:MaxSubSum(a,0,d-1)1易算出时间复杂度为 c、代码实现#includeusing namespace:std;#define d 10int median(int x,int y,int xLeft,int xRight,int yLeft,int yRight) if(xLeft=xRight) return (xxLeft+yyLeft)/2; int xm=(xLeft+xRight)/2; int ym=(yLeft+yRight)/2; if(xLeft+xRight)%2=
6、0) /为奇数 if(xxmyym) median(x,y,xm,xRight,yLeft,ym); else median(x,y,xLeft,xm,ym,yRight); else /为偶数 if(xxmyym) median(x,y,xm+1,xRight,yLeft,ym); else median(x,y,xLeft,xm,ym+1,yRight); int main() int m;int ad,bd; coutEnter dimension m:m; coutEnter array a:endl; for(int i=0;iai; coutEnter array b:endl;
7、for(int j=0;jbj; int mid=median(a,b,0,m-1,0,m-1); coutThe median is:midendl; return 0;运行结果为:4. 设计一个O(n*n)时间的算法,找出由n个数组成的序列最长单调递增子序列. P87页(参考P56页) (动态规划算法)a、算法思路:序列X按非递减顺序排列,形成新序列Y,问题就转变成求解X和Y的LCS。b、时间复杂度:使用快速排序,则排序过程的时间复杂度为O(nlgn),而求两个序列的LCS的时间复杂度为O(n2)(因为X、Y长度相等),综合可知该解法的时间复杂度为O(n2)。c、代码实现#include#
8、define m 10/快速排序void QuickSort(int R,int s,int t) int i=s,j=t; int tmp; if(si&Rj=tmp) j-; Ri=Rj; while(ij&Ri=tmp) i+; Rj=Ri; Ri=tmp; QuickSort(R,s,i-1); QuickSort(R,i+1,t); /找出最长公共子序列void LCSLength(int x,int y,int n,int cmm,int bmm) int i,j; for(i=0;in;i+) c0i=0; ci0=0; for(i=0;in;i+) for(j=0;j=cij-
9、1) cij=ci-1j; bij=2; else cij=cij-1; bij=3; void LCS(int i,int j,int *x,int bmm) if(i0|j0) return; if(bij=1) LCS(i-1,j-1,x,b); coutxi ; else if(bij=2) LCS(i-1,j,x,b); else LCS(i,j-1,x,b);void main() int xm,ym,d; cout请输入元素个数d; cout请输入元素endl; for(int i=0;ixi; yi=xi; int cmm=0,bmm=0; QuickSort(x,0,d-1)
10、; LCSLength(x,y,d,c,b); cout最长单调递增子序列为:endl; LCS(d-1,d-1,x,b);结果为:7.礼物分配问题. 两兄弟Alan 和Bob, 共同分配n个礼物. 每个礼物只能分给其中的一个人,且不能分成两个.每个礼物i 的价值为vi, 为正整数.设 a 和 b 分别表示Alan 和 Bob所收到的礼物的总价值, V=, 为所有礼物的总价值. 为使两兄弟高兴,我们希望尽可能地均分这些礼物, 即 |a-b| 打到最小 试设计-O(n*V)时间的动态规划算法,使得|a-b| 达到最小, 并求出礼物的分割集合 (P77页)(动态规划算法) 8.(4.7)多处最优服务问题 P131页 (贪婪算法) (与十人打水的问题一样)
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1