算法实验报告.docx
- 文档编号:28114956
- 上传时间:2023-07-08
- 格式:DOCX
- 页数:12
- 大小:99.61KB
算法实验报告.docx
《算法实验报告.docx》由会员分享,可在线阅读,更多相关《算法实验报告.docx(12页珍藏版)》请在冰豆网上搜索。
算法实验报告
实验一分治与递归算法的应用
一、实验目的
1.掌握分治算法的基本思想(分-治-合)、技巧和效率分析方法。
2.熟练掌握用递归设计分治算法的基本步骤(基准与递归方程)。
3.学会利用分治算法解决实际问题。
二.实验容
金块问题
老板有一袋金块(共n块,n是2的幂(n≥2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。
假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。
并对自己的程序进行复杂性分析。
3.问题分析:
一般思路:
假设袋中有n个金块。
可以用函数Max(程序1-31)通过n-1次比较找到最重的金块。
找到最重的金块后,可以从余下的n-1个金块中用类似法通过n-2次比较找出最轻的金块。
这样,比较的总次数为2n-3。
分治法:
当n很小时,比如说,n≤2,识别出最重和最轻的金块,一次比较就足够了。
当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]为最大的重量。
首先处理n≤1的情况。
若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)//当只有一个数时,直接返回该值 { floatmax; max=g[right]; returnmax; } if(right-left==1) { floatLM,RM; LM=g[left]; RM=g[right]; return(max(LM,RM)); } if(right-left>1) { floatLM,RM; intmid=(left+right)/2;//取中点 LM=Search_Max(g,left,mid); RM=Search_Max(g,mid,right);//左半部分,右半部分的最大值比较找最大 return(max(LM,RM)); } } floatSearch_Min(floatg[],intleft,intright)//用二分法递归找最小值 { if(left==right) { floatmin; min=g[right]; returnmin; } if(right-left==1) { floatLM,RM; LM=g[left]; RM=g[right]; return(min(LM,RM)); } if(right-left>1) { floatLM,RM; intmid=(left+right)/2; LM=Search_Min(g,left,mid); 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<<"最轻的金块: "< return0; } 实验结果 输入金块数量: 5 得到最轻和最重的金块 实验总结 通过这次实验,我深刻了解到分治法的实用性,有效性。 当遇到规模较大的问题,用我们以前学过的方法就太不明智了。 将原问题划分成若干个较小规模的子问题,再继续求解,划分,能够简化问题。 递归法,是一个很重要的方法,具有结构自相似的特性,刚开始学习编写的时候遇到了很多问题,不知道要找边界,不知道如何划分问题。 关于这次算法,我觉得,类的部分还是一个难点,也就是说,不会将问题分解成抽象的概念,这也是我以后需要重点学习的地方。 实验二动态规划算法的应用 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、实验容 最长单调递增子序列问题 设计一个O(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]结尾的最长递增子序列的长度,状态转移方程表示为:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 实验 报告