算法课程所有实验报告.docx
- 文档编号:24151660
- 上传时间:2023-05-24
- 格式:DOCX
- 页数:25
- 大小:207.70KB
算法课程所有实验报告.docx
《算法课程所有实验报告.docx》由会员分享,可在线阅读,更多相关《算法课程所有实验报告.docx(25页珍藏版)》请在冰豆网上搜索。
算法课程所有实验报告
实验一分治与递归算法的应用3
题目二:
线性时间选择3
一、实验目的3
二、问题描述:
3
三、算法设计3
四、程序调试及运行结果分析4
五、实验总结4
题目四:
金块问题6
一、实验目的6
二、问题描述6
三、算法设计7
四、程序调试及运行结果分析8
源程序8
实验二贪心算法的应用11
题目三:
程序存储问题11
一、实验目的11
二、问题描述:
11
三、算法分析11
四、程序调试及运行结果分析12
五、实验总结13
源代码13
题目四:
汽车加油问题14
一、实验目的14
二、问题描述14
三、算法分析15
四、程序调试及运行结果分析16
五、实验总结16
程序清单16
实验三动态规划算法的应用17
题目一:
数塔问题17
一、实验目的17
二、问题描述17
三、算法设计18
四、程序调试及运行结果分析19
五、实验总结19
附:
源代码20
题目三:
CommonSubsequence21
一、实验目的21
二、问题描述21
三、算法设计22
四、程序调试及运行结果分析23
五、实验总结23
附录:
程序清单(程序过长,可附主要部分)24
实验一分治与递归算法的应用
题目二:
线性时间选择
一、实验目的
1.掌握分治算法的基本思想(分-治-合)、技巧和效率分析方法。
2.熟练掌握用递归设计分治算法的基本步骤(基准与递归方程)。
3.学会利用分治算法解决实际问题。
二、问题描述:
题目二:
线性时间选择
给定n个元素和一个整数k,要求用O(n)时间找出这n个元素中第k小元素。
三、算法设计
当我们求解某些问题的时候,由于这些问题处理的数据相当多,或求解过程相当复杂,使使得直接求解法在时间上相当长,或根本无法直接求出。
对于类似的问题,我们往往先把它分解成几个子问题,找到求解子问题的方法后,再找到合适的方法,把他们组合成求解整个问题的方法。
如果这些子问题还较大,难以解决,可以再把他们分成更小的子问题,以此类推,知道可以求出解为止。
这就是分治的基恩思想。
四、程序调试及运行结果分析
图一
图二
五、实验总结
通过实验了解并掌握了动态规划的思想,解题步骤,进一步了解了好的算法带来的好处。
附录:
程序清单(程序过长,可附主要部分)
#include
intpartition(intr[],intlow,inthigh)
{
inti=low,j=high;
while(i { while(i if(i { inttemp=r[i]; r[i]=r[j]; r[j]=temp; i++; } while(i if(i { inttemp=r[i]; r[i]=r[j]; r[j]=temp; j--; } } returni; } intseclectmink(intr[],intlow,inthigh,intk) { ints; s=partition(r,low,high); if(s==k) returnr[s]; if(s>k) returnseclectmink(r,low,s-1,k); else returnseclectmink(r,s+1,high,k); } intmain() { inti,j,n; inta[100]; printf("请输入数组的大小(0--100之间): "); scanf("%d",&n); printf("请输入数组: "); for(i=1;i<=n;i++) { scanf("%d",&a[i]); } printf("请输入你要找的第K小的数(1-%d之间): ",n); scanf("%d",&j); seclectmink(a,1,n,j); printf("第%d小的数是: %d\n",j,a[j]); return0; } 题目四: 金块问题 一、实验目的 1.掌握分治算法的基本思想(分-治-合)、技巧和效率分析方法。 2.熟练掌握用递归设计分治算法的基本步骤(基准与递归方程)。 3.学会利用分治算法解决实际问题。 二、问题描述 老板有一袋金块(共n块,n是2的幂(n≥2)),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块。 假设有一台比较重量的仪器,希望用最少的比较次数找出最重和最轻的金块。 并对自己的程序进行复杂性分析。 三、算法设计 分而治之方法与软件设计的模块化方法非常相似。 为了解决一个大的问题,可以: 1)把它分成两个或多个更小的问题;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,则递归地应用分而治之方法 假设6个金块重量如下(以找最轻金块为例): 264381 一分为二(两组): 【264】【381】 一分为二(四组): 【26】【4】【38】【1】 解较小子问题: 2431 合并子问题解: 21 lminrmin 四、程序调试及运行结果分析 图一 图二 源程序 #include usingnamespacestd; #definen6 floata[n]; voidmaxmin(inti,intj,float&fmax,float&fmin) { intmid; floatlmax,lmin,rmax,rmin; if(i==j) { fmax=a[i]; fmin=a[i]; return; } elseif(i==j-1) if(a[i] { fmax=a[j]; fmin=a[i]; return; } else { fmax=a[i]; fmin=a[j]; return; } else { mid=(i+j)/2; maxmin(i,mid,lmax,lmin); maxmin(mid+1,j,rmax,rmin); if(lmax>rmax) fmax=lmax; else fmax=rmax; if(lmin>rmin) fmin=rmin; else fmin=lmin; return; } } intmain() { inti; a[0]=1; cout<<"输入各金块的重量: "< for(i=0;i cin>>a[i]; for(i=0;i cout< cout< floatfmax,fmin; maxmin(0,n-1,fmax,fmin); cout<<"最重的"< return0; } 实验二贪心算法的应用 题目三: 程序存储问题 一、实验目的 1.掌握贪心算法的基本概念和两个基本要素 2.熟练掌握贪心算法解决问题的基本步骤。 3.学会利用贪心算法解决实际问题。 二、问题描述: 设有n个程序{1,2,3,…,n}要存放在长度为L的磁带上。 程序i存放在磁带上的长度是li,1≤i≤n。 要求确定这n个程序在磁带上的一个存储方案,使得能够在磁带上存储尽可能多的程序。 输入数据中,第一行是2个正整数,分别表示程序文件个数和磁带长度L。 接下来的1行中,有n个正整数,表示程序存放在磁带上的长度。 输出为最多可以存储的程序个数。 输入数据示例 650 231388020 输出数据 5 三、算法分析 题目要求计算给定长度的磁带最多可存储的程序个数,先对程序的长度从小到大排序,再采用贪心算法求解。 a.定义数组a[n]存储n个程序的长度,s为磁带的长度; b.调用库函数sort(a,a+n)对程序的长度从小到大排序; c.函数most()计算磁带最多可存储的程序数,采用while循环依次对排序后的程序 长度进行累加,用i计算程序个数,用sum计算程序累加长度(初始i=0,sum=0): ①sum=sum+a[i]; ②若sum<=s,i加1,否则i为所求; ③i=n时循环结束; d.若while循环结束时仍有sum<=s,则n为所求。 四、程序调试及运行结果分析 图一 图二 五、实验总结 基础虽然简单但有时候还是要掌握牢固才好,粗心有时候会耽误很多不必要的时间要尽量克服,在写程序的时候认真才行。 有时候还是不能偷懒,要尽量想想其他更优的方法, 基础不扎实,在调用函数的时候在开头没有定义,不过经同学指点就可以改,应 该学会更深一层思考以及用多种不同的方法实现,比如排序方法有很多种,可以借此机会多思考采用各种排序方法,从而巩固了以前的知识。 考虑问题要全面,虽然有时候会将问题复杂化但是至少思考过程能学到很多东西,这样会使逻辑越来越严谨。 源代码 #include #include usingnamespacestd; inta[10000]; intmost(intn,ints) { inti=0,sum=0; while(i { sum=a[i]+sum; if(sum<=s) i++; else returni; } returnn; } main() { inti,n,s; while(scanf("%d%d\n",&n,&s)! =EOF) { for(i=0;i scanf("%d",&a[i]); sort(a,a+n); printf("%d\n",most(n,s)); } return0; } 题目四: 汽车加油问题 一、实验目的 1.掌握贪心算法的基本概念和两个基本要素 2.熟练掌握贪心算法解决问题的基本步骤。 3.学会利用贪心算法解决实际问题。 二、问题描述 一辆汽车加满油后,可行使n千米。 旅途中有若干个加油站。 若要使沿途加油次数最少,设计一个有效算法,对于给定的n和k个加油站位置,指出应在哪些加油站停靠加油才能使加油次数最少。 输入数据中,第一行有2个正整数,分别表示汽车加满油后可行驶n千米,且旅途中有k个加油站。 接下来的1行中,有k+1个整数,表示第k个加油站与第k-1个加油站之间的距离。 第0个加油站表示出发地,汽车已加满油。 第k+1个加油站表示目的地。 输出为最少的加油次数,如果无法到达目的地,则输出“NoSolution”。 实验提示: 把两加油站的距离放在数组中,a[1..k]表示从起始位置开始跑,经过k个加油站,a[i]表示第i-1个加油站到第i个加油站的距离。 汽车在运行的过程中如果能跑到下一个站则不加油,否则要加油。 输入数据示例 77 12345166 输出数据 4 三、算法分析 题目要求编程计算最少加油次数,若无法到达目的地,则输出“NoSolution”。 该题可以采用贪心算法求解,从出发地开始进行判别: 油足够则继续行驶;油不够则加油,计算加油次数;油满仍不够则“NoSolution”。 a.n表示汽车加满油后可行驶n公里,k表示出发地与目的地之间有k个加油站; b.定义数组s[k+1]存储加油站之间的距离: 用s[i]标记第i个加油站与第i+1个加 油站之间的距离(第0个加油站为出发地,汽车已加满油;第k+1个加油站为目的地); c.用t计算加油次数,用l标记在未加油的情况下汽车还能行驶l公里,采用for 循环从出发地开始(即i=0)依次计算加油次数: ①若s[i]>n,则输出“NoSolution”; ②若l l=n-s[i],t++; ③行驶s[i]公里后,汽车还能行驶n-s[i]公里; ④i=k时循环结束;t即为所求。 四、程序调试及运行结果分析 五、实验总结 通过本次实验了解和掌握了贪心算法,在解决问题的时候要有耐心,不要怕麻烦,开始的时候没有思路的话先想简单的,一步一步往下走,慢慢的思路就会越来越清晰。 程序清单 #include usingnamespacestd; voidmain() { intn,k; ints[1000]; inti,t,l,tag=1; cin>>n>>k; for(i=0;i<=k;i++) cin>>s[i]; l=n; t=0; for(i=0;i<=k;i++) { if(s[i]<=n) { if(s[i]>l) { l=n-s[i]; t++; } else l=l-s[i]; } else { cout<<"nosolution"< tag=0; break; } } if(tag==1) cout< } 实验三动态规划算法的应用 题目一: 数塔问题 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、问题描述 给定一个数塔,其存储形式为如下所示的下三角矩阵。 在此数塔中,从顶部出发,在每一节点可以选择向下走还是向右走,一直走到底层。 请找出一条路径,使路径上的数值和最大。 输入样例(数塔): 9 1215 1068 21895 19710416 输出样例(最大路径和): 59 三、算法设计 此题如用枚举,在薯塔层数稍大的情况下路径数目庞大,用贪心找不到最优解,可以用动态规划自顶向下的分析,自低向上的计算。 从顶点出发向左还是向右取决于在哪边可以找到最大值,只有左右两条道路上的最大值求出来了,才能做出决策。 求解时从底层开始,层层递进,最后得到最大值。 用n表示数塔的行数,用二维数组intmap[6][6]存储数塔 四、程序调试及运行结果分析 图片一 图片二 五、实验总结 动态规划算法通常用于求解具有某种最优性质的问题。 在这类问题中,可能会有许多可行解。 每一个解都对应于一个值,我们希望找到具有最优值的解。 动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。 与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。 若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。 如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。 我们可以用一个表来记录所有已解的子问题的答案。 不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。 附: 源代码 #include intmap[6][6]; intmain() { intn,i,j; n=5; printf("输入数塔的行数"); scanf("%d",&n); printf("请输入数塔\n"); for(i=1;i<=n;i++) { for(j=1;j<=i;j++) { scanf("%d",&map[i][j]); } } for(i=n-1;i>=1;i--)//从倒数第二行开始 { for(j=1;j<=n-1;j++) { if(map[i+1][j]>map[i+1][j+1]) map[i][j]+=map[i+1][j]; else map[i][j]+=map[i+1][j+1]; } } printf("最大路径和"); printf("%d\n",map[1][1]); return0; } 题目三: CommonSubsequence 一、实验目的 1.掌握动态规划算法的基本思想,包括最优子结构性质和基于表格的最优值计算方法。 2.熟练掌握分阶段的和递推的最优子结构分析方法。 3.学会利用动态规划算法解决实际问题。 二、问题描述 题目三: CommonSubsequence Asubsequenceofagivensequenceisthegivensequencewithsomeelements(possiblenone)leftout.GivenasequenceX= Theprograminputisfromatextfile.Eachdatasetinthefilecontainstwostringsrepresentingthegivensequences.Thesequencesareseparatedbyanynumberofwhitespaces.Theinputdataarecorrect.Foreachsetofdatatheprogramprintsonthestandardoutputthelengthofthemaximum-lengthcommonsubsequencefromthebeginningofaseparateline. 输入样例 abcfbcabfcab programmingcontest abcdmnp 输出样例 4 2 0 3、算法设计 由最长公共子序列问题的最优子结构性质可知,要找出X= 当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。 当xm≠yn时,必须解两个子问题,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列。 这两个公共子序列中较长者即为X和Y的一个最长公共子序列。 若i=0或j=0a[i][j]=0 若s1[i-1]==s2[j-1]a[i][j]=a[i-1][j-1]+1; 若s1[i-1]! =s2[j-1]a[i][j]=max{a[i-1][j],a[i][j-1]} 四、程序调试及运行结果分析 图一 图二 五、实验总结 这个问题开始的时候感觉很麻烦,画图,思考,一会把自己绕晕了,错了一小步,好久没看出来,以后还是要认真、小心。 附录: 程序清单(程序过长,可附主要部分) #include #include inta[1001][1001]; intlcs(char*s1,char*s2) { intm=strlen(s1),n=strlen(s2); inti,j; a[0][0]=0; for(i=1;i<=m;++i)a[i][0]=0; for(i=1;i<=n;++i)a[0][i]=0; for(i=1;i<=m;i++) for(j=1;j<=n;++j) { if(s1[i-1]==s2[j-1])a[i][j]=a[i-1][j-1]+1; elseif(a[i-1][j]>a[i][j-1])a[i][j]=a[i-1][j]; elsea[i][j]=a[i][j-1]; } returna[m][n]; } intmain() { intn; printf("输入要比较的字符串的对数: "); scanf("%d",&n); while(n--) { charc[1008],b[1008]; scanf("%s%s",c,b); printf("%d\n",lcs(b,c)); }return0;}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 课程 所有 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)