算法设计与分析报告.docx
- 文档编号:30614408
- 上传时间:2023-08-18
- 格式:DOCX
- 页数:13
- 大小:20.60KB
算法设计与分析报告.docx
《算法设计与分析报告.docx》由会员分享,可在线阅读,更多相关《算法设计与分析报告.docx(13页珍藏版)》请在冰豆网上搜索。
算法设计与分析报告
算法设计与分析报告
◎小组成员:
陈壮茂,陈振凯,张建龙,莫媚,林晓丹
◎报告内容:
1.给定数组a[0:
n-1],试设计一个算法,在最坏情况下用n+[logn]-2次比较找出a[0:
n-1]中的元素的最大值和次大值.
◎分析:
a[0:
n-1]是说这个数组有n个元素,序号为0到n-1n+[logn]-2就是一个算法复杂度,应该是n+logn的整数部分-2。
◎首先对数组相邻的两个进行比较,将大的放在后面,小的放在前面,然后在两个数中小的所有数选出最小,同时也在两个数中大的所有数选出最大的。
可以得出总的比较次数:
(int)(n/2)+2*((int)(n/2)-1).
◎代码如下:
#include
#defineN9
intk=0;
intmax(intnum[],intn)
{
intbig[N],i;
cout<<"max"< for(i=0;2*i<=n-2;i++) { if(k++,num[i]>num[n-i-1]) big[i]=num[i]; else big[i]=num[n-i-1]; } if(n%2! =0) { big[i]=num[i]; i++; } if(i==1) returnbig[0]; else returnmax(big,i); } intfun(int&second,intnum[],intn) { intbig[N],small[N],i,number; cout<<"fun"< for(i=0;2*i<=n-2;i++) { if(k++,num[i]>num[n-i-1]) { big[i]=num[i]; small[i]=num[n-i-1]; } else { big[i]=num[n-i-1]; small[i]=num[i]; } } if(n%2) { big[i]=num[i]; i++; } number=max(small,i); second=second>number? second: number; k++; if(i==1) returnbig[0]; else returnfun(second,big,i); } voidmain() { intnum[N],second,i,large; cout<<"请输入"< for(i=0;i cin>>num[i]; second=num[0]>num[1]? num[1]: num[0]; k++; large=fun(second,num,N); cout<<"最大值是: "< "< "< } ◎最初数据 a[1] a[2] a[3] a[4] a[5] 4 3 6 9 8 ◎运行过程中的数据变化与结果 Second: 3 big: 8;9;6 small: 4;3 second: 4 big: 8;9 samll: 6 second: 6 big: 9 small: 8 second: 8 big: 9 2.求数列的最大子段和(要求时间复杂为nlogn) ◎分析: 给出n个整数(亦正亦负)组成的序列a[1],a[2],a[3],…,a[n],求该序列中a[i]+a[i+1]+…+a[j]的子段和的最大值。 当最大子段和为负数时,规定此数列的最大子段和为0. ◎算法和思路: 依据上面的描述,所求的点i最大路径和c[i]应该为: Max{a[i],c[i-1]+a[i]} intmaxSubSum(intP[]) {inti; intmaxsum=0; intc=0; for(i=0;i { if(c>0) c+=P[i]; else c=P[i]; if(c>maxsum) maxsum=c; } returnmaxsum; } ◎主函数: intmain() {intA[MAX]; inti,sum; printf("Pleaseinputaarray: "); for(i=0;i scanf("%d",&A[i]); sum=maxSubSum(A); printf("TheMaxsubsumis: %d",sum); return0; } ◎当输入数据为: 8,4,-1,14 ◎运行过程: c=8+4=12 (C=8+4-1)<12(和会下降,于是不能赋值给maxsum) (C=8+4-1+14)>12(和又上升了,赋值给了C值) 3.设计一个O(n*n)时间的算法,找出由n个数组成的序列最长单调递增子序列. ◎分析: (1)递推关系 ①对a(n)来说,由于它是最后一个数,所以当a(n)从开始查找时,只存在长度为1的不下降序列。 ②若从a(n-1)开始查找,则存在下面两种可能性: 若a(n-1) 若a(n-1)>a(n),则存在长度为的不下降序列。 ③若从a(i)开始,此时最长不下降序列应该按下列方法求出: 在a(i+1),a(i+2),…,a(n)中,找出一个起始数据比a(i)大且最长的不下降序列,作为它的后续。 (2)数据结构设计 用数组b[i]记录点i到得最长的不下降子序列的长度,记录点i在最长的不下降子序列的后继续数据编号。 ◎算法如下: Intmaxn=100; Inta[maxn],b[maxn],c[maxn]; Main() {intn,I,j,max,p; input(n); for(i=1;i<=n;i=i+1) {input(a[i]); b[i]=1; c[i]=0;} For(i=n-1;i>=1;i=i-1) {max=0;p=0; for(j=i+1;j<=n;j=j+1) if(a[i]max) {max=b[j];p=j;} if(p<>0) {b[i]=b[p]+1; c[i]=p;} } Max=0;p=0; For(i=1;i<=n;i++) if(b[i]>max) {max=b[i]; p=I;} Print(“maxlong=“,max); Print(“resultis: ”); While(p<>0) {print(a[p]); p=c[p];} } ◎经过循环,数据的变化 a[1]=3;a[2]=18;a[3]=7 b[1]=1;b[2]=1;b[3]=1 c[1]=0;c[2]=0;c[3]=0 ◎变化结果: a[1]=3;a[2]=18;a[3]=7 b[1]=2;b[2]=1;b[3]=1 c[1]=2;c[2]=0;c[3]=0 4.礼物分配问题.两兄弟Alan和Bob,共同分配n个礼物.每个礼物只能分给其中的一个人,且不能分成两个.每个礼物i的价值为vi,为正整数.设a和b分别表示Alan和Bob所收到的礼物的总价值,V= 为所有礼物的总价值.为使两兄弟高兴,我们希望尽可能地均分这些礼物,即|a-b|打到最小。 ◎分析: 该题目要求使得所分的礼物差值最小; 首先,我们知道礼物总价值为V= ;由于要使差值最小,则a与b要最接近于1/2V;故可以设a=1/2V+t,b=1/2V-t;故|a-b|=|(1/2V+t)-(1/2V-t)|=2t;而t=a-1/2V;其中V为已知,则只要a为大于1/2V的最小数即可。 。 。 依照次数学思路,我们可以将该方法进行具体话: 既是将数组降序排列(这一点很重要,可以用数学分析法进行证明),然后将数组的一个元素赋给a,如果a加上该元素后大于b,则将下一个元素赋给b,循环进行判断直至数组结束。 。 。 数学证明过程略 ◎代码如下: #include usingnamespacestd; #defineMaxSize50 void collat(intn,intv) { inta=0; intb=0; intAlan[MaxSize]={0},Bob[MaxSize]={0},r=0,s=0; for(inti=n;i>0;i--) { if(a>b) { b=b+v*i; Bob[r]=v*i; r++; } else { a=a+v*i; Alan[s]=v*i; s++; } } cout<<"Alan分配到的礼物为:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 设计 分析 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)