计算机算法设计与分析实验报告
算法设计与分析的实验报告

实验一递归与分治策略一、实验目的1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。
二、实验内容1、①设a[0:n-1]是已排好序的数组。
请写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。
当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
②写出三分搜索法的程序。
三、实验要求(1)用分治法求解上面两个问题;(2)再选择自己熟悉的其它方法求解本问题;(3)上机实现所设计的所有算法;四、实验过程设计(算法设计过程)1、已知a[0:n-1]是一个已排好序的数组,可以采用折半查找(二分查找)算法。
如果搜索元素在数组中,则直接返回下表即可;否则比较搜索元素x与通过二分查找所得最终元素的大小,注意边界条件,从而计算出小于x的最大元素的位置i和大于x的最小元素位置j。
2、将n个元素分成大致相同的三部分,取在数组a的左三分之一部分中继续搜索x。
如果x>a[2(n-1)/3],则只需在数组a的右三分之一部分中继续搜索x。
上述两种情况不成立时,则在数组中间的三分之一部分中继续搜索x。
五、实验结果分析二分搜索法:三分搜索法:时间复杂性:二分搜索每次把搜索区域砍掉一半,很明显时间复杂度为O(log n)。
(n代表集合中元素的个数)三分搜索法:O(3log3n)空间复杂度:O(1)。
六、实验体会本次试验解决了二分查找和三分查找的问题,加深了对分治法的理解,收获很大,同时我也理解到学习算法是一个渐进的过程,算法可能一开始不是很好理解,但是只要多看几遍,只看是不够的还要动手分析一下,这样才能学好算法。
七、附录:(源代码)二分搜索法:#include<iostream.h>#include<stdio.h>int binarySearch(int a[],int x,int n){int left=0;int right=n-1;int i,j;while(left<=right){int middle=(left+right)/2;if(x==a[middle]){i=j=middle;return 1;}if(x>a[middle])left=middle+1;else right=middle-1;}i=right;j=left;return 0;}int main(){ int a[10]={0,1,2,3,4,5,6,7,8,9};int n=10;int x=9;if(binarySearch(a,x,n))cout<<"找到"<<endl;elsecout<<"找不到"<<endl;return 0;}实验二动态规划——求解最优问题一、实验目的1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。
《算法设计与分析》实验报告实验一...

《算法设计与分析》实验报告实验一递归与分治策略应用基础学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期第九周一、实验目的1、理解递归的概念和分治法的基本思想2、了解适用递归与分治策略的问题类型,并能设计相应的分治策略算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:以下题目要求应用递归与分治策略设计解决方案,本次实验成绩按百分制计,完成各小题的得分如下,每小题要求算法描述准确且程序运行正确。
1、求n个元素的全排。
(30分)2、解决一个2k*2k的特殊棋牌上的L型骨牌覆盖问题。
(30分)3、设有n=2k个运动员要进行网球循环赛。
设计一个满足要求的比赛日程表。
(40分)提交结果:算法设计分析思路、源代码及其分析说明和测试运行报告。
三、设计分析四、算法描述及程序五、测试与分析六、实验总结与体会#include "iostream"using namespace std;#define N 100void Perm(int* list, int k, int m){if (k == m){for (int i=0; i<m; i++)cout << list[i] << " ";cout << endl;return;}else{for (int i=m; i<k; i++){swap(list[m], list[i]);Perm(list, k, m+1);swap(list[m], list[i]);}}}void swap(int a,int b){int temp;temp=a;a=b;b=temp;}int main(){int i,n;int a[N];cout<<"请输入排列数据总个数:";cin>>n;cout<<"请输入数据:";for(i=0;i<n;i++){cin>>a[i];}cout<<"该数据的全排列:"<<endl;Perm(a,n,0);return 0;}《算法设计与分析》实验报告实验二递归与分治策略应用提高学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期一、实验目的1、深入理解递归的概念和分治法的基本思想2、正确使用递归与分治策略设计相应的问题的算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:从以下题目中任选一题完成,要求应用递归与分治策略设计解决方案。
算法课设实验报告(3篇)

第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。
为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。
二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。
1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。
(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。
- 对每种算法进行时间复杂度和空间复杂度的分析。
- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。
(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。
- 编写三种排序算法的代码。
- 分析代码的时间复杂度和空间复杂度。
- 编写测试程序,生成随机测试数据,测试三种算法的性能。
- 比较三种算法的运行时间和内存占用。
2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。
(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。
- 分析贪心算法的正确性,并证明其最优性。
(3)实验步骤:- 分析活动选择问题的贪心策略。
- 编写贪心算法的代码。
- 分析贪心算法的正确性,并证明其最优性。
- 编写测试程序,验证贪心算法的正确性。
3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。
(2)实验内容:- 实现一个动态规划算法问题,如背包问题。
- 分析动态规划算法的正确性,并证明其最优性。
(3)实验步骤:- 分析背包问题的动态规划策略。
- 编写动态规划算法的代码。
- 分析动态规划算法的正确性,并证明其最优性。
- 编写测试程序,验证动态规划算法的正确性。
三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。
算法分析与设计实验报告合并排序快速排序

算法分析与设计实验报告:合并排序与快速排序一、引言算法是计算机科学中非常重要的一部分,它涉及到解决问题的方法和步骤。
合并排序和快速排序是两种经典而常用的排序算法。
本文将对这两种排序算法进行分析和设计实验,通过对比它们的性能和效率,以期得出最优算法。
二、合并排序合并排序是一种分治算法,它将原始数组不断分解为更小的数组,直到最后细分为单个元素。
然后,再将这些单个元素两两合并,形成一个有序数组。
合并排序的核心操作是合并两个有序的数组。
1. 算法步骤(1)将原始数组分解为更小的子数组,直到每个子数组只有一个元素;(2)两两合并相邻的子数组,同时进行排序,生成新的有序数组;(3)重复步骤(2),直到生成最终的有序数组。
2. 算法性能合并排序的最优时间复杂度为O(nlogn),其中n为待排序数组的长度。
无论最好情况还是最坏情况,合并排序的复杂度都相同。
合并排序需要额外的存储空间来存储临时数组,所以空间复杂度为O(n)。
三、快速排序快速排序也是一种分治算法,它将原始数组根据一个主元(pivot)分成两个子数组,一个子数组的元素都小于主元,另一个子数组的元素都大于主元。
然后,递归地对这两个子数组进行排序,最后得到有序数组。
快速排序的核心操作是划分。
1. 算法步骤(1)选择一个主元(pivot),可以是随机选择或者固定选择第一个元素;(2)将原始数组根据主元划分为两个子数组,一个子数组的元素都小于主元,另一个子数组的元素都大于主元;(3)递归地对这两个子数组进行快速排序;(4)重复步骤(2)和(3),直到每个子数组只有一个元素,即得到最终的有序数组。
2. 算法性能快速排序的平均时间复杂度为O(nlogn),其中n为待排序数组的长度。
最坏情况下,当每次选择的主元都是最小或最大元素时,时间复杂度为O(n^2)。
快速排序是原地排序,不需要额外的存储空间,所以空间复杂度为O(1)。
四、实验设计为了验证合并排序和快速排序的性能和效率,我们设计以下实验:1. 实验目的:比较合并排序和快速排序的时间复杂度和空间复杂度。
算法分析与设计实验报告

算法分析与设计实验报告算法分析与设计实验报告一、引言算法是计算机科学的核心,它们是解决问题的有效工具。
算法分析与设计是计算机科学中的重要课题,通过对算法的分析与设计,我们可以优化计算机程序的效率,提高计算机系统的性能。
本实验报告旨在介绍算法分析与设计的基本概念和方法,并通过实验验证这些方法的有效性。
二、算法分析算法分析是评估算法性能的过程。
在实际应用中,我们常常需要比较不同算法的效率和资源消耗,以选择最适合的算法。
常用的算法分析方法包括时间复杂度和空间复杂度。
1. 时间复杂度时间复杂度衡量了算法执行所需的时间。
通常用大O表示法表示时间复杂度,表示算法的最坏情况下的运行时间。
常见的时间复杂度有O(1)、O(log n)、O(n)、O(n log n)和O(n^2)等。
其中,O(1)表示常数时间复杂度,O(log n)表示对数时间复杂度,O(n)表示线性时间复杂度,O(n log n)表示线性对数时间复杂度,O(n^2)表示平方时间复杂度。
2. 空间复杂度空间复杂度衡量了算法执行所需的存储空间。
通常用大O表示法表示空间复杂度,表示算法所需的额外存储空间。
常见的空间复杂度有O(1)、O(n)和O(n^2)等。
其中,O(1)表示常数空间复杂度,O(n)表示线性空间复杂度,O(n^2)表示平方空间复杂度。
三、算法设计算法设计是构思和实现算法的过程。
好的算法设计能够提高算法的效率和可靠性。
常用的算法设计方法包括贪心算法、动态规划、分治法和回溯法等。
1. 贪心算法贪心算法是一种简单而高效的算法设计方法。
它通过每一步选择局部最优解,最终得到全局最优解。
贪心算法的时间复杂度通常较低,但不能保证得到最优解。
2. 动态规划动态规划是一种将问题分解为子问题并以自底向上的方式求解的算法设计方法。
它通过保存子问题的解,避免重复计算,提高算法的效率。
动态规划适用于具有重叠子问题和最优子结构的问题。
3. 分治法分治法是一种将问题分解为更小规模的子问题并以递归的方式求解的算法设计方法。
算法与分析实验报告

算法与分析实验报告一、引言算法是现代计算机科学中的核心概念,通过合理设计的算法可以解决复杂的问题,并提高计算机程序的执行效率。
本次实验旨在通过实际操作和数据统计,对比分析不同算法的执行效率,探究不同算法对于解决特定问题的适用性和优劣之处。
二、实验内容本次实验涉及两个经典的算法问题:排序和搜索。
具体实验内容如下:1. 排序算法- 冒泡排序- 插入排序- 快速排序2. 搜索算法- 顺序搜索- 二分搜索为了对比不同算法的执行效率,我们需要设计合适的测试用例并记录程序执行时间进行比较。
实验中,我们将使用随机生成的整数数组作为排序和搜索的测试数据,并统计执行时间。
三、实验步骤1. 算法实现与优化- 实现冒泡排序、插入排序和快速排序算法,并对算法进行优化,提高执行效率。
- 实现顺序搜索和二分搜索算法。
2. 数据生成- 设计随机整数数组生成函数,生成不同大小的测试数据。
3. 实验设计- 设计实验方案,包括测试数据的规模、重复次数等。
4. 实验执行与数据收集- 使用不同算法对随机整数数组进行排序和搜索操作,记录执行时间。
- 多次重复同样的操作,取平均值以减小误差。
5. 数据分析与结果展示- 将实验收集到的数据进行分析,并展示在数据表格或图表中。
四、实验结果根据实验数据的收集与分析,我们得到以下结果:1. 排序算法的比较- 冒泡排序:平均执行时间较长,不适用于大规模数据排序。
- 插入排序:执行效率一般,在中等规模数据排序中表现良好。
- 快速排序:执行效率最高,适用于大规模数据排序。
2. 搜索算法的比较- 顺序搜索:执行时间与数据规模成线性关系,适用于小规模数据搜索。
- 二分搜索:执行时间与数据规模呈对数关系,适用于大规模有序数据搜索。
实验结果表明,不同算法适用于不同规模和类型的问题。
正确选择和使用算法可以显著提高程序的执行效率和性能。
五、实验总结通过本次实验,我们深入了解了不同算法的原理和特点,并通过实际操作和数据分析对算法进行了比较和评估。
算法设计与分析实验报告(中南民族大学)
院系:计算机科学学院专业:年级:课程名称:算法设计与分析基础班号:组号:指导教师:年月日实验结果及分析1.求最大数2.递归法与迭代法性能比较递归迭代3.改进算法1.利用公式法对第n项Fibonacci数求解时可能会得出错误结果。
主要原因是由于double类型的精度还不够,所以程序算出来的结果会有误差,要把公式展开计算。
2.由于递归调用栈是一个费时的过程,通过递归法和迭代法的比较表明,虽然递归算法的代码更精简更有可读性,但是执行速度无法满足大数问题的求解。
3.在当前计算机的空间较大的情况下,在一些速度较慢的问题中,空间换时间是一个比较周全的策略。
实验原理(算法基本思想)定义:若A=(a ij), B=(b ij)是n×n的方阵,则对i,j=1,2,…n,定义乘积C=A⋅B 中的元素c ij为:1.分块解法通常的做法是将矩阵进行分块相乘,如下图所示:二.Strassen解法分治法思想将问题实例划分为同一问题的几个较小的实例。
对这些较小实例求解,通常使用递归方法,但在问题规模足够小时,也会使用另一种算法。
如果有必要,合并这些问题的解,以得到原始问题的解。
求解矩阵相乘的DAC算法,使用了strassen算法。
DAC(A[],B[],n){If n=2 使用7次乘法的方法求得解ElseDivide(A)//把A分成4块Divide(B)//把B分成4块调用7次strassen算法求得解的4块合并这4块得到解并返回}伪代码Serial_StrassenMultiply(A, B, C) {T1 = A0 + A3;T2 = B0 + B3;StrassenMultiply(T1, T2, M1);T1 = A2 + A3;StrassenMultiply(T1, B0, M2);T1 = (B1 - B3);StrassenMultiply (A0, T1, M3);T1 = B2 - B0;StrassenMultiply(A3, T1, M4);T1 = A0 + A1;StrassenMultiply(T1, B3, M5);T1 = A2 – A0;T2 = B0 + B1;StrassenMultiply(T1, T2, M6);T1 = A1 – A3;T2 = B2 + B3;StrassenMultiply(T1, T2, M7);C0 = M1 + M4 - M5 + M7C1 = M3 + M5C2 = M2 + M4C3 = M1 - M2 + M3 + M6}实验结果及分析时间复杂度1.分块相乘总共用了8次乘法,因而需要Θ(n log28)即Θ(n3)的时间复杂度。
算法设计与分析实验报告
算法设计与分析实验报告实验一全排列、快速排序【实验目的】1. 掌握全排列的递归算法。
2. 了解快速排序的分治算法思想。
【实验原理】一、全排列全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。
任何n个字符集的排列都可以与1~n的n个数字的排列一一对应,因此在此就以n 个数字的排列为例说明排列的生成法。
n个字符的全体排列之间存在一个确定的线性顺序关系。
所有的排列中除最后一个排列外,都有一个后继;除第一个排列外,都有一个前驱。
每个排列的后继都可以从它的前驱经过最少的变化而得到,全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。
二、快速排序快速排序(Quicksort)是对冒泡排序的一种改进。
它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
【实验内容】1.全排列递归算法的实现。
2.快速排序分治算法的实现。
【实验结果】1. 全排列:2. 快速排序:实验二最长公共子序列、活动安排问题【实验目的】1. 了解动态规划算法设计思想,运用动态规划算法实现最长公共子序列问题。
2. 了解贪心算法思想,运用贪心算法设计思想实现活动安排问题。
【实验原理】一、动态规划法解最长公共子序列设序列X=和Y=的一个最长公共子序列Z=,则:i. 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;ii. 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列;iii. 若xm≠yn且z k≠yn ,则Z是X和Yn-1的最长公共子序列。
其中Xm-1=,Yn-1=,Zk-1=。
最长公共子序列问题具有最优子结构性质。
由最长公共子序列问题的最优子结构性质可知,要找出X=和Y=的最长公共子序列,可按以下方式递归地进行:当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。
算法设计与分析实验报告
实验一找最大和最小元素与归并分类算法实现(用分治法)一、实验目的1.掌握能用分治法求解的问题应满足的条件;2.加深对分治法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
二、实验内容1、找最大和最小元素输入n 个数,找出最大和最小数的问题。
2、归并分类将一个含有n个元素的集合,按非降的次序分类(排序)。
三、实验要求(1)用分治法求解问题(2)上机实现所设计的算法;四、实验过程设计(算法设计过程)1、找最大和最小元素采用分治法,将数组不断划分,进行递归。
递归结束的条件为划分到最后若为一个元素则max和min都是这个元素,若为两个取大值赋给max,小值给min。
否则就继续进行划分,找到两个子问题的最大和最小值后,比较这两个最大值和最小值找到解。
2、归并分类使用分治的策略来将一个待排序的数组分成两个子数组,然后递归地对子数组进行排序,最后将排序好的子数组合并成一个有序的数组。
在合并过程中,比较两个子数组的首个元素,将较小的元素放入辅助数组,并指针向后移动,直到将所有元素都合并到辅助数组中。
五、源代码1、找最大和最小元素#include<iostream>using namespace std;void MAXMIN(int num[], int left, int right, int& fmax, int& fmin); int main() {int n;int left=0, right;int fmax, fmin;int num[100];cout<<"请输入数字个数:";cin >> n;right = n-1;cout << "输入数字:";for (int i = 0; i < n; i++) {cin >> num[i];}MAXMIN(num, left, right, fmax, fmin);cout << "最大值为:";cout << fmax << endl;cout << "最小值为:";cout << fmin << endl;return 0;}void MAXMIN(int num[], int left, int right, int& fmax, int& fmin) { int mid;int lmax, lmin;int rmax, rmin;if (left == right) {fmax = num[left];fmin = num[left];}else if (right - left == 1) {if (num[right] > num[left]) {fmax = num[right];fmin = num[left];}else {fmax = num[left];fmin = num[right];}}else {mid = left + (right - left) / 2;MAXMIN(num, left, mid, lmax, lmin);MAXMIN(num, mid+1, right, rmax, rmin);fmax = max(lmax, rmax);fmin = min(lmin, rmin);}}2、归并分类#include<iostream>using namespace std;int num[100];int n;void merge(int left, int mid, int right) { int a[100];int i, j,k,m;i = left;j = mid+1;k = left;while (i <= mid && j <= right) {if (num[i] < num[j]) {a[k] = num[i++];}else {a[k] = num[j++];}k++;}if (i <= mid) {for (m = i; m <= mid; m++) {a[k++] = num[i++];}}else {for (m = j; m <= right; m++) {a[k++] = num[j++];}}for (i = left; i <= right; i++) { num[i] = a[i];}}void mergesort(int left, int right) { int mid;if (left < right) {mid = left + (right - left) / 2;mergesort(left, mid);mergesort(mid + 1, right);merge(left, mid, right);}}int main() {int left=0,right;int i;cout << "请输入数字个数:";cin >> n;right = n - 1;cout << "输入数字:";for (i = 0; i < n; i++) {cin >> num[i];}mergesort(left,right);for (i = 0; i < n; i++) {cout<< num[i];}return 0;}六、运行结果和算法复杂度分析1、找最大和最小元素图1-1 找最大和最小元素结果算法复杂度为O(logn)2、归并分类图1-2 归并分类结果算法复杂度为O(nlogn)实验二背包问题和最小生成树算法实现(用贪心法)一、实验目的1.掌握能用贪心法求解的问题应满足的条件;2.加深对贪心法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
常见算法设计实验报告(3篇)
第1篇一、实验目的通过本次实验,掌握常见算法的设计原理、实现方法以及性能分析。
通过实际编程,加深对算法的理解,提高编程能力,并学会运用算法解决实际问题。
二、实验内容本次实验选择了以下常见算法进行设计和实现:1. 排序算法:冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。
2. 查找算法:顺序查找、二分查找。
3. 图算法:深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)。
4. 动态规划算法:0-1背包问题。
三、实验原理1. 排序算法:排序算法的主要目的是将一组数据按照一定的顺序排列。
常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等。
2. 查找算法:查找算法用于在数据集中查找特定的元素。
常见的查找算法包括顺序查找和二分查找。
3. 图算法:图算法用于处理图结构的数据。
常见的图算法包括深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)等。
4. 动态规划算法:动态规划算法是一种将复杂问题分解为子问题,通过求解子问题来求解原问题的算法。
常见的动态规划算法包括0-1背包问题。
四、实验过程1. 排序算法(1)冒泡排序:通过比较相邻元素,如果顺序错误则交换,重复此过程,直到没有需要交换的元素。
(2)选择排序:每次从剩余元素中选取最小(或最大)的元素,放到已排序序列的末尾。
(3)插入排序:将未排序的数据插入到已排序序列中适当的位置。
(4)快速排序:选择一个枢纽元素,将序列分为两部分,使左侧不大于枢纽,右侧不小于枢纽,然后递归地对两部分进行快速排序。
(5)归并排序:将序列分为两半,分别对两半进行归并排序,然后将排序好的两半合并。
(6)堆排序:将序列构建成最大堆,然后重复取出堆顶元素,并调整剩余元素,使剩余元素仍满足最大堆的性质。
2. 查找算法(1)顺序查找:从序列的第一个元素开始,依次比较,直到找到目标元素或遍历完整个序列。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告课程名称:算法设计与分析班级:软件121 实验日期:2014/11/19 姓名:熊齐超学号:1208060220 指导教师:程欣宇实验序号:一实验成绩:一、实验名称分治算法实验- 棋盘覆盖问题二、实验目的及要求1、熟悉递归算法编写;2、理解分治算法的特点;3、掌握分治算法的基本结构。
三、实验环境Visual C++四、实验内容根据教材上分析的棋盘覆盖问题的求解思路,进行验证性实验;要求完成棋盘覆盖问题的输入、分治求解、输出。
有余力的同学尝试消去递归求解。
五、算法描述及实验步骤分治算法原理:分治算法将大的分解成形状结构相同的子问题,并且不断递归地分解,直到子问题规模小到可以直接求解。
棋盘覆盖问题描述:在一个2k x 2k个方格组成的棋盘中恰有一个方格与其他的不同称为特殊方格,想要求利用四种L型骨牌(每个骨牌可覆盖三个方格)不相互重叠覆盖的将除了特殊方格外的其他方格覆盖。
实验步骤:1、定义用于输入和输出的数据结构;2、完成分治算法的编写;3、测试记录结构;4、有余力的同学尝试不改变输入输出结构,将递归消除,并说明能否不用栈,直接消除递归,为什么?六、调试过程及实验结果程序的执行结果如下图所示:七、总结通过对本次的棋盘覆盖问题的求解,对递归与分治策略有了更进一步的了解,分治法的设计思路是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
在实际的上机操作过程中,不仅是让我们了解数算法的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次实习可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。
八、附录源程序(核心代码):#include<iostream>using namespace std;int tile=1; //L型骨牌的编号(递增)int board[100][100]; //棋盘void chessBoard ( int tr, int tc, int dr, int dc, int size ){if ( size==1 ) //棋盘方格大小为1,说明递归到最里层return;int t=tile++; //每次递增1int s=size/2; //棋盘中间的行、列号(相等的)//检查特殊方块是否在左上角子棋盘中if ( dr<tr+s && dc<tc+s ) //在chessBoard ( tr, tc, dr, dc, s );else //不在,将该子棋盘右下角的方块视为特殊方块{board[tr+s-1][tc+s-1]=t;chessBoard ( tr, tc, tr+s-1, tc+s-1, s );}//检查特殊方块是否在右上角子棋盘中if ( dr<tr+s && dc>=tc+s ) //在chessBoard ( tr, tc+s, dr, dc, s );else //不在,将该子棋盘左下角的方块视为特殊方块{board[tr+s-1][tc+s]=t;chessBoard ( tr, tc+s, tr+s-1, tc+s, s );}//检查特殊方块是否在左下角子棋盘中if ( dr>=tr+s && dc<tc+s ) //在chessBoard ( tr+s, tc, dr, dc, s );else //不在,将该子棋盘右上角的方块视为特殊方块{board[tr+s][tc+s-1]=t;chessBoard ( tr+s, tc, tr+s, tc+s-1, s );}//检查特殊方块是否在右下角子棋盘中if ( dr>=tr+s && dc>=tc+s ) //在chessBoard ( tr+s, tc+s, dr, dc, s );else //不在,将该子棋盘左上角的方块视为特殊方块{board[tr+s][tc+s]=t;chessBoard ( tr+s, tc+s, tr+s, tc+s, s );}}void main(){int size;cout<<"输入棋盘的size(大小必须是2的n次幂): ";cin>>size;int index_x,index_y;cout<<"输入特殊方格位置的坐标: ";cin>>index_x>>index_y;chessBoard ( 0,0,index_x,index_y,size );for ( int i=0; i<size; i++ ){for ( int j=0; j<size; j++ )cout<<board[i][j]<<" ";cout<<endl;}}贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告课程名称:算法设计与分析班级:软件121 实验日期:2014 11 14姓名:熊齐超学号:1208060220 指导教师:程欣宇实验序号:二实验成绩:一、实验名称动态规划实验- 滑雪问题二、实验目的及要求1、学会使用在线测评的算法题目评分系统;2、通过直观的应用问题,加深对动态规划算法的理解;三、实验环境任意C或C++编写调试工具,北京大学ICPC在线测评系统POJ四、实验内容1、找到题号为1088的题目-滑雪,阅读题目,建立其最优解的递归表达式;3、使用备忘录式的动态规划算法,实现本题;4、进行简单测试,完成之后提交到POJ系统。
五、算法描述及实验步骤动态规划算法原理:分治算法将大的问题变成小的问题来解决,但是如果划分过程中出现重叠子问题,就可能导致大量的重复计算。
为了避免这些重复的计算,可以考虑的一个办法就是动态规划算法。
为了使用动态规划算法,问题还必须具备最优子结构,即问题的最优解包含了子问题的最优解。
滑雪问题描述:Michael喜欢滑雪百这并不奇怪,因为滑雪的确很刺激。
可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。
Michael想知道载一个区域中最长底滑坡。
区域由一个二维数组给出。
数组的每个数字代表点的高度。
下面是一个例子1 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。
在上面的例子中,一条可滑行的滑坡为24-17-16-1。
当然25-24-23-...-3-2-1更长。
事实上,这是最长的一条。
Input输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。
下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output输出最长区域的长度。
实验步骤:1、建立滑雪问题的解的递归表达式递归表达式如下:if(dp[i][j] < DP(i+a[k][0],j+a[k][1]) + 1)dp[i][j] = DP(i+a[k][0],j+a[k][1]) + 1;2、构造算法框架(1)首先定义一个状态转移函数,用来遍历搜索所需的最长路径int DP(int i,int j){...}(2)在主函数中调用DP(i,j)函数,将所求最长路径的存放在变量ans中int main(){...}3、分析出算法复杂度因为DP(int i,int j)函数每调用一次,都要对i,j周围的四个数进行比较,这样的工作要重复进行,故需要O(n2)的时间。
六、调试过程及实验结果程序的执行结果如下图所示:七、总结通过对本次的滑雪问题的动态规划算法求解,对动态规划算法有了更进一步的了解,动态规划算法的设计思路是:分治算法将大的问题变成小的问题来解决,但是如果划分过程中出现重叠子问题,就可能导致大量的重复计算。
为了避免这些重复的计算,可以考虑的一个办法就是动态规划算法。
为了使用动态规划算法,问题还必须具备最优子结构,即问题的最优解包含了子问题的最优解。
在实际的上机操作过程中,不仅是让我们了解数算法的理论知识,更重要的是培养解决实际问题的能力,所以相信通过此次实习可以提高我们分析设计能力和编程能力,为后续课程的学习及实践打下良好的基础。
八、附录源程序(核心代码):#include <iostream>#include <cstring>using namespace std;/******************************************************************** **********************/int h[105][105];//输入的高度值int dis_sk[101][101];//记录了每一个点作为起点的最长长度int dx[]={-1,1,0,0};//为了方便上下左右侧的滑行的最大距离而使用的数组int dy[]={0,0,-1,1};int r,c;/**********************************判断是否越界******************************************/bool in_bound(int i,int j){return i >= 0 && i < r && j >= 0 && j < c;}/***************以查询方式写的动态规划实现的从i,j下滑最大距离:*******************/int dis(int i,int j){int temp;if(dis_sk[i][j])return dis_sk[i][j];for(int k = 0; k < 4; k++){if(in_bound(i+dx[k],j+dy[k])){if(h[i][j] > h[ i+dx[k] ][ j+dy[k] ]){temp = dis(i+dx[k],j+dy[k]);//递归求dis(i+dx[k],j+dy[k]),并保存在临时变量temp 中dis_sk[i][j] = dis_sk[i][j] > temp ? dis_sk[i][j] : temp + 1;//如果dis_sk[i][j]比temp 小,则取temp+1}}}return dis_sk[i][j];}/************main函数,取dis(i,j)的最大者就是所求的最长区域的长度:********************/int main(){int max_dis = 0;int temp;int i,j;cin >> r >> c;for(i = 0; i < r; i++)for(j = 0; j < c; j++){cin >> h[i][j];dis_sk[i][j] = 0;}for(i = 0; i < r; i++)for(j = 0; j < c; j++){temp = dis(i,j);max_dis = max_dis > temp ? max_dis : temp;}cout << max_dis + 1 << endl;//因为初始值是0,所以最后要加1 return 0;}贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告课程名称:算法设计与分析班级:软件121 实验日期:2014-11-21姓名:熊齐超学号:1208060220 指导教师:程欣宇实验序号:三实验成绩:一、实验名称贪心算法实验- 包装问题二、实验目的及要求1、使用在线测评的算法题目评分系统来测试所写代码;2、通过直观的应用问题,加深对贪心算法的理解;三、实验环境任意C或C++编写调试工具,北京大学ICPC在线测评系统POJ四、实验内容1、登陆POJ系统,找到题号为1017的题目-包装;2、阅读题目,分析出求解该问题的思路;3、使用贪心算法,实现本题;4、进行简单测试,完成之后提交到POJ系统。