算法设计与分析报告.docx

上传人:b****8 文档编号:30614408 上传时间:2023-08-18 格式:DOCX 页数:13 大小:20.60KB
下载 相关 举报
算法设计与分析报告.docx_第1页
第1页 / 共13页
算法设计与分析报告.docx_第2页
第2页 / 共13页
算法设计与分析报告.docx_第3页
第3页 / 共13页
算法设计与分析报告.docx_第4页
第4页 / 共13页
算法设计与分析报告.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

算法设计与分析报告.docx

《算法设计与分析报告.docx》由会员分享,可在线阅读,更多相关《算法设计与分析报告.docx(13页珍藏版)》请在冰豆网上搜索。

算法设计与分析报告.docx

算法设计与分析报告

算法设计与分析报告

◎小组成员:

陈壮茂,陈振凯,张建龙,莫媚,林晓丹

◎报告内容:

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分配到的礼物为:

"<

for(intj=0;j

{

cout<

}

cout<

cout<<"Bob分配到的礼物为:

"<

for(intk=0;k

{

cout<

}

cout<

cout<<"Alan分配到的礼物总价值为:

"<

cout<<"Bob分配到的礼物总价值为:

"<

}

intmain()

{

intnum,v;

cout<<"请输入礼物的个数:

";

cin>>num;

cout<<"请输入单位礼物的价值:

";

cin>>v;

collat(num,v);

return0;

}

7.键盘输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按左右次序将组成一个新的正整数.编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数最小.

◎代码如下:

#include

usingnamespacestd;

#defineMaxSize50

#defineT10

voidOrderArray(intN,intS)

{intarray[MaxSize]={0};

inti=0,j,a=N,max,tag;

while(N>=10)

{array[i]=N%10;

N=N/10;

i++;}

array[i]=N;

for(j=0;j

{for(intp=i;p>=0;p--)

{if(array[p]>array[p-1])

{for(ints=p;s<=i;s++)

array[s]=array[s+1];

i--;break;}

}

}

for(intr=i;r>=0;r--)

cout<

intmain()

{

OrderArray(12435863,2);

return0;

}

8.最佳调度问题。

假设有个任务由个并行的机器完成。

完成任务i个需要的时间为。

试设计一个算法找出完成这个任务的最佳调度,使得完成全部任务的时间最早。

◎分析:

可使用贪心算法解决该题目,对于n个任务,k个并行的机器,如果n<=k,则最优调度为每一台机器完成一个任务,完成总时间为n;2.如果n>=k,则先将n个任务进行降序排序,然后完成前k个任务,接着如果完成任务的机器还有时间完成后面的任务,则将任务该由机器完成,直至所有任务完成;

◎代码如下:

#include

usingnamespacestd;

voidBestAlloct(intarray[],intn,intk)

{

inti,j,change=1,sum=0;

inttemp;

for(i=n-1;i>0&&change;i--)

{

change=0;

for(j=0;j

if(array[j]

{

change=1;

temp=array[j];

array[j]=array[j+1];

array[j+1]=temp;

}

}

if(n<=k)

{

cout<<"最少时间为:

"<

}

else

{

for(intr=0;r

{

sum=sum+array[r];

for(intp=1;p

{

intsum2=array[r+p];

for(ints=r+k;s

{

if(sum2+array[s]<=array[r])

{

sum2=sum2+array[s];

array[s]=0;

}

}

}

}

Cout<<”最少时间为:

”<

}

}

intmain()

{

inta[6]={15,14,12,10,6};

BestAlloct(a,6,3);

return0;

}

 

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1