算法实验报告.docx

上传人:b****9 文档编号:25273874 上传时间:2023-06-06 格式:DOCX 页数:11 大小:41.73KB
下载 相关 举报
算法实验报告.docx_第1页
第1页 / 共11页
算法实验报告.docx_第2页
第2页 / 共11页
算法实验报告.docx_第3页
第3页 / 共11页
算法实验报告.docx_第4页
第4页 / 共11页
算法实验报告.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

算法实验报告.docx

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

算法实验报告.docx

算法实验报告

实验一分治与递归算法的应用

一、实验目的

1.掌握分治算法的基本思想(分-治-合)、技巧和效率分析方法。

2.熟练掌握用递归设计分治算法的基本步骤(基准与递归方程)。

3.学会利用分治算法解决实际问题。

二.实验容

金块问题

老板有一袋金块(共n块,n是2的幕(n》2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。

假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。

并对自己的程序进行复杂性分析。

三.问题分析:

一般思路:

假设袋中有n个金块。

可以用函数Max(程序

1-31)通过n-1次比较找到最重的金块。

找到最重的金块后,可以从余下的n-1个金块中用类似法通过n-2次比较找出最轻的金块。

这样,比较的总次数为2n-3。

分治法:

当n很小时,比如说,nW2,识别出最重和最轻的金块,一次比较就足够了。

当n较大时(n>2),第一步,把这袋金块平分成两个小袋A和B。

第二步,分别找出在A和B中最重和最轻的金块。

设A中最重和最轻的金块分别为HA与LA,以此类推,B中最重和最轻的金块分别为HB和LB。

第三步,通过比较HA和HB,可以找到所有金块中最重的;通过比较LA和LB,可以找到所有金块中最轻的。

在第二步中,若n>2,则递归地应用分而治之方法

程序设计

据上述步骤,可以得出程序14-1的非递归代码。

该程序用于寻找到数组w[0:

n-1]中的最小数和最大数,若n<1,则程序返回false,否则返回true。

当n》1时,程序14-1给Min和Max置初值以使w[Min]是最小的重量,w[Max]为最大的重量。

首先处理nW1的情况。

若n>1且为奇数,第一个重量w[0]将成为最小值和最大值的候选值,因此将有偶,数个重量值w[1:

n-1]参与for循环。

当n是偶数时,首先将两个重量值放在for循环外进行比较,较小和较大的重量值分别置为Min和Max,因此也有偶数个重量值w[2:

n-1]参与for循环。

在for循环中,外层if通过比较确定(w[i],w[i+1])中的较大和较小者。

此工作与前面提到的分而治之算法步骤中的2)相对应,而层的if负责找出较小重量值和较大重量值中的最小值和最大值,这个工作对应于3)°for循环将每一对重量值中较小值和较大值分别与当前的最小值w[Min]和最大值w[Max]进行比较,根据比较结果来修改Min和Max(如果必要)。

源程序

#include

#include

#include

usingnamespacestd;0

floatmax(floatg1,floatg2)//比较找大值

{

return(g1>g2?

g1:

g2);

}

floatmin(floatg1,floatg2)//比较找小值

{

return(g1

g1:

g2);

}

floatSearch_Max(floatg[],intleft,intright)//用二分法递归找最大值

{

if(left==right)//当只有一个数时,直接返回该值

foafmax-maxugmghF「efummax-isghf—CDftHHl)宀

foafLM.RM-

LMHg=e3

RMHgrighFrefum(max(LM・RM))-

 

isghreftvl)宀

foafLM.RM-

inf3S^?

SS対甘猗

LMHSea「chlMax(g」efLmidx

RMHSea「chlMax(Fmid2gh>?

//m>?

&®“氓>?

&®3>”bFbkr2.um3ax(LM・RM)x

 

foafSearchlMin(f_oafg=5-f-eenflighf)//sN®M®&^>、Mt宀if(-eftHHIIghf)宀

foafmm

minugrighq八

「efummin八

isghf—CDftHHl)

 

LMHg=e3RMHgrighF

r2.um(min(LM・RM))八

isghreftvl)宀

foafLM.RM-inf龙牙^耳+^-三)^八

LMHSearchlMin(g」eftmid)_

 

RM=Search_Min(g,mid,right);//左半部分,右半部分的最小值比较找最小

return(min(LM,RM));

}

}

intmain()

{

floatgold[100];

intn;

cout<<"请输入金块的数目:

";

cin>>n;

cout<<"请输入各金块的重量:

";

for(inti=0;i

{

cin>>gold[i];

}

cout<<"最重的金块:

"<

cout<<"最轻的金块:

"<

实验结果

输入金块数量:

5

得到最轻和最重的金块

 

I;・E:

VJt档资料\06lDebug\OO5ab

 

实验总结

通过这次实验,我深刻了解到分治法的实用性,有效性。

当遇到规模较大的问题,用我们以前学过的方法就太不明智了。

将原问题划分成若干个较小规模的子问题,再继续求解,划分,能够简化问题。

递归法,是一个很重要的方法,具有结构自相似的特性,刚开始学习编写的时候遇到了很多问题,不知道要找边界,不知道如何划分问题。

关于这次算法,我觉得,类的部分还是一个难点,也就是说,不会将问题分解成抽象的概念,这也是我以后需要重点学习的地方。

实验二动态规划算法的应用

一、实验目的

1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。

2.熟练掌握分阶段的和递推的最优子结构分析方法。

3.学会利用动态规划算法解决实际问题。

二、实验容

最长单调递增子序列问题

设计一个0(n2)复杂度的算法,找出由n个数组成的序列的最长单调递增子序列。

思路分析

1、把a1,a2,...,an排序,假设得到a'1,a'2,...,a'n然后求a的a'的

最长公共子串,这样总的时间复杂度为o(nlg(n))+o(n^2)=o(n^2);

2、动态规划的思路:

另设一辅助数组b,定义b[n]表示以a[n]结尾的最长递增子序列的长度,则状态转移方程如下:

b[k]=max(max(b[j]|a[j]

设辅助数组b[],定义b[n]表示以a[n]结尾的最长递增子序列的长度,状态转移方程表示为:

b[k]=max(max(b[j]|a[j]

其中ov二kv二n-1,在a[k]前面找到满足a[j]

小的a[j],此时a[k]形成序列,长度为1,继续计算,最后整个序列的最长递增子序列:

max(b[k]|0<二k<二n-1),此时时间复杂度仍为

0(nA2)。

另外定义一数组c,c中元素满足c[b[k]]=a[k],即当递增子序列的长度为b[k]时子序列的末尾元素为c[b[k]]=a[k]。

实现代码

第一种思路:

#includevstdio.h>//时间复杂度O(nA2)intmain()

inti,j,k,n,a[100],b[100],c[100],max;

while(scanf("%d",&n)!

=EOF)

{

for(i=0;i

b[0]=1;//初始化,以a[0]结尾的最长递增子序列长度为1

c[0]=a[0];k=1;

for(i=1;i

{

b[i]=1;〃b[i]最小值为1

for(j=0;j

if(a[i]>a[j]&&b[j]+1>b[i])

{

b[i]=b[i]+1;

}

}

for(max=i=0;i

if(b[i]>max)

max=b[i];

printf("%d\n",max);

}

return0;

}

运行结果

实验总结

通过实现动态规划的这个题目,对动态规划算法有了进一步的了

解。

先分析问题,判断是否具有最优子结果和重叠字问题的性质

实验三贪心算法的应用

一、实验目的

1.掌握贪心算法的基本概念和两个基本要素

2.熟练掌握贪心算法解决问题的基本步骤。

3.学会利用贪心算法解决实际问题。

二、实验容

题目三:

程序存储问题

设有n个程序{1,2,3,…,n}要存放在长度为L的磁带上。

程序i存放在磁带上的长度是li,1

要求确定这n个程序在磁带上的一个存储方案,使得能够在磁带上存储尽可能多的程序。

输入数据中,第一行是2个正整数,分别表示程序文件个数和磁带长度L。

接下来

的1行中,有n个正整数,表示程序存放在磁带上的长度。

输出为最多可以存储的程序个数。

输入数据示例

650

231388020

输出数据

5

3.题目分析:

题目要求计算给定长度的磁带最多可存储的程序个数,先对程序

的长度从小到大排序,再采用贪心算法求解。

3、算法设计:

a.定义数组a[n]存储n个程序的长度,s为磁带的长度;

b.调用库函数sort(a,a+n)对程序的长度从小到大排序;

c.函数most()计算磁带最多可存储的程序数,采用while

循环依次对排序后的程序

长度进行累加,用i计算程序个数,用sum计算程序累加长度

(初始i=0,sum=0):

1sum=sum+a[i];

2若sum<=s,i加1,否则i为所求;

3i=n时循环结束;

d.若while循环结束时仍有sum<=s,则n为所求。

源程序:

#include

usingnamespacestd

#include

inta[1000000];

intmost(int*a,intn,ints)

{

inti=0,sum=0;

while(i

{

sum二a[i]+sum;

if(sum<=s)

i++;

elsereturni;

}

returnn;

}

main()

{

inti,n,s;

scanf("%d%d\n",&n,&s);

for(i=0;i

scanf("%d",&a[i]);

sort(a,a+n);

printf("%d",most(a,n,s));

return0;

}

实验总结

此次实验让我对贪心算法的思想有了初步的了解,并且学会了用贪心算法解决一些实际问题。

两个程序中都运用了循环语句,在编写代码时,在循环语句的设置中遇到许多问题,经过调试最终解决。

所以,以后应当多做一些循环语句的练习。

通过实践加强编程的熟练程度

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

当前位置:首页 > 初中教育 > 数学

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

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