算法实验报告
- 格式:doc
- 大小:234.52 KB
- 文档页数:29
一、实验背景随着计算机科学技术的不断发展,算法作为计算机科学的核心内容之一,其重要性日益凸显。
为了验证和评估不同算法的性能,我们进行了一系列算法实验,通过对比分析实验结果,以期为后续算法研究和优化提供参考。
二、实验方法本次实验选取了三种常见的算法:快速排序、归并排序和插入排序,分别对随机生成的数据集进行排序操作。
实验数据集的大小分为10000、20000、30000、40000和50000五个级别,以验证算法在不同数据量下的性能表现。
实验过程中,我们使用Python编程语言实现三种算法,并记录每种算法的运行时间。
同时,为了确保实验结果的准确性,我们对每种算法进行了多次运行,并取平均值作为最终结果。
三、实验结果1. 快速排序快速排序是一种高效的排序算法,其平均时间复杂度为O(nlogn)。
从实验结果来看,快速排序在所有数据量级别下均表现出较好的性能。
在数据量较小的10000和20000级别,快速排序的运行时间分别为0.05秒和0.1秒;而在数据量较大的40000和50000级别,运行时间分别为0.8秒和1.2秒。
总体来看,快速排序在各个数据量级别下的运行时间均保持在较低水平。
2. 归并排序归并排序是一种稳定的排序算法,其时间复杂度也为O(nlogn)。
实验结果显示,归并排序在数据量较小的10000和20000级别下的运行时间分别为0.15秒和0.25秒,而在数据量较大的40000和50000级别,运行时间分别为1.5秒和2.5秒。
与快速排序相比,归并排序在数据量较小的情况下性能稍逊一筹,但在数据量较大时,其运行时间仍然保持在较低水平。
3. 插入排序插入排序是一种简单易实现的排序算法,但其时间复杂度为O(n^2)。
实验结果显示,插入排序在数据量较小的10000和20000级别下的运行时间分别为0.3秒和0.6秒,而在数据量较大的40000和50000级别,运行时间分别为8秒和15秒。
可以看出,随着数据量的增加,插入排序的性能明显下降。
一、实验背景分治算法是一种常用的算法设计方法,其基本思想是将一个复杂问题分解成若干个相互独立的小问题,然后将小问题递归求解,最终将子问题的解合并为原问题的解。
分治算法具有高效性、可扩展性和易于实现等优点,被广泛应用于各个领域。
本实验旨在通过实现分治算法解决实际问题,掌握分治算法的设计思想,并分析其时间复杂度。
二、实验目的1. 理解分治算法的基本思想;2. 掌握分治算法的递归实现方法;3. 分析分治算法的时间复杂度;4. 应用分治算法解决实际问题。
三、实验内容本实验选择两个分治算法:快速排序和合并排序。
1. 快速排序快速排序是一种高效的排序算法,其基本思想是将待排序序列分为两个子序列,其中一个子序列的所有元素均小于另一个子序列的所有元素,然后递归地对两个子序列进行快速排序。
(1)算法描述:① 选择一个基准值(pivot),通常取序列的第一个元素;② 将序列分为两个子序列,一个子序列包含所有小于基准值的元素,另一个子序列包含所有大于基准值的元素;③ 递归地对两个子序列进行快速排序。
(2)代码实现:```cvoid quickSort(int arr[], int left, int right) {if (left < right) {int pivot = arr[left];int i = left;int j = right;while (i < j) {while (i < j && arr[j] >= pivot) {j--;}arr[i] = arr[j];while (i < j && arr[i] <= pivot) {i++;}arr[j] = arr[i];}arr[i] = pivot;quickSort(arr, left, i - 1);quickSort(arr, i + 1, right);}}```2. 合并排序合并排序是一种稳定的排序算法,其基本思想是将待排序序列分为两个子序列,分别对两个子序列进行排序,然后将排序后的子序列合并为一个有序序列。
《算法设计与分析》实验报告实验一递归与分治策略应用基础学号:**************姓名:*************班级:*************日期: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、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:从以下题目中任选一题完成,要求应用递归与分治策略设计解决方案。
算法分析与设计实验报告--回溯法实验目的:通过本次实验,掌握回溯法的基本原理和应用,能够设计出回溯法算法解决实际问题。
实验内容:1.回溯法概述回溯法全称“试探回溯法”,又称“逐步退化法”。
它是一种通过不断试图寻找问题的解,直到找到解或者穷尽所有可能的解空间技术。
回溯法的基本思路是从问题的某一个初始状态开始,搜索可行解步骤,一旦发现不满足求解条件的解就回溯到上一步,重新进行搜索,直到找到解或者所有可能的解空间已经搜索完毕。
2.回溯法的基本应用回溯法可用于求解许多 NP 问题,如 0/1 背包问题、八皇后问题、旅行商问题等。
它通常分为两种类型:一种是通过枚举所有可能的解空间来寻找解;另一种则是通过剪枝操作将搜索空间减少到若干种情况,大大减少了搜索时间。
3.回溯法的解题思路(1)问题分析:首先需要对问题进行分析,确定可行解空间和搜索策略;(2)状态表示:将问题的每一种状况表示成一个状态;(3)搜索策略:确定解空间的搜索顺序;(4)搜索过程:通过逐步试探,不断扩大搜索范围,更新当前状态;(5)终止条件:在搜索过程中,如果找到了满足要求的解,或者所有的可行解空间都已搜索完毕,就结束搜索。
4.八皇后问题八皇后问题是指在一个 8x8 的棋盘上放置八个皇后,使得任意两个皇后都不在同一行、同一列或同一对角线上。
通过回溯法可以求解出所有的可能解。
实验过程:回溯法的实现关键在于搜索空间的剪枝,避免搜索无用的解;因此,对于八皇后问题,需要建立一个二维数组来存放棋盘状态,以及一个一维数组来存放每行放置的皇后位置。
从第一行开始搜索,按照列的顺序依次判断当前的空位是否可以放置皇后,如果可以,则在相应的位置标记皇后,并递归到下一行;如果不能,则回溯到上一行,重新搜索。
当搜索到第八行时,获取一组解并返回。
代码实现:```pythondef is_valid(board, row, col):for i in range(row):if board[i] == col or abs(board[i] - col) == abs(i - row):return Falsereturn True实验结果:当 n=4 时,求得的所有可行解如下:```[[1, 3, 0, 2],[2, 0, 3, 1]]```本次实验通过实现回溯法求解八皇后问题,掌握了回溯法的基本原理和应用,并对回溯法的核心思想进行了深入理解。
第1篇一、实验目的1. 了解现代密码学的基本原理和数论基础知识;2. 掌握非对称密码体制的著名代表RSA加密算法的工作原理和流程;3. 设计实现一个简单的密钥系统;4. 掌握常用加密算法AES和DES的原理及实现。
二、实验内容1. RSA加密算法实验2. AES加密算法实验3. DES加密算法实验三、实验原理1. RSA加密算法RSA算法是一种非对称加密算法,由罗纳德·李维斯特、阿迪·沙米尔和伦纳德·阿德曼三位密码学家于1977年提出。
其基本原理是选择两个大质数p和q,计算它们的乘积n=pq,并计算欧拉函数φ(n)=(p-1)(q-1)。
选择一个整数e,满足1<e<φ(n)且e与φ(n)互质。
计算e关于φ(n)的模逆元d。
公开密钥为(e,n),私有密钥为(d,n)。
加密过程为C=Me mod n,解密过程为M=Cd mod n。
2. AES加密算法AES(Advanced Encryption Standard)是一种分组加密算法,采用128位分组大小和128、192或256位密钥长度。
AES算法主要分为四个阶段:初始轮、密钥扩展、中间轮和最终轮。
每个轮包括字节替换、行移位、列混淆和轮密钥加。
3. DES加密算法DES(Data Encryption Standard)是一种分组加密算法,采用64位分组大小和56位密钥长度。
DES算法主要分为16轮,每轮包括置换、置换-置换、S盒替换和密钥加。
四、实验步骤及内容1. RSA加密算法实验(1)选择两个大质数p和q,计算n=pq和φ(n)=(p-1)(q-1);(2)选择一个整数e,满足1<e<φ(n)且e与φ(n)互质,计算e关于φ(n)的模逆元d;(3)生成公开密钥(e,n)和私有密钥(d,n);(4)用公钥对明文进行加密,用私钥对密文进行解密。
2. AES加密算法实验(1)选择一个128、192或256位密钥;(2)初始化初始轮密钥;(3)进行16轮加密操作,包括字节替换、行移位、列混淆和轮密钥加;(4)输出加密后的密文。
操作系统实验报告——调度算法1. 实验目的本实验旨在探究操作系统中常用的调度算法,通过编写代码模拟不同的调度算法,了解它们的特点和应用场景。
2. 实验环境本次实验使用的操作系统环境为Linux,并采用C语言进行编码。
3. 实验内容3.1 调度算法1:先来先服务(FCFS)FCFS调度算法是一种简单且常见的调度算法。
该算法按照进程到达的先后顺序进行调度。
在本实验中,我们使用C语言编写代码模拟FCFS算法的调度过程,并记录每个进程的等待时间、周转时间和响应时间。
3.2 调度算法2:最短作业优先(SJF)SJF调度算法是一种非抢占式的调度算法,根据进程的执行时间来选择下一个要执行的进程。
在本实验中,我们使用C语言编写代码模拟SJF算法的调度过程,并计算每个进程的等待时间、周转时间和响应时间。
3.3 调度算法3:轮转调度(Round Robin)Round Robin调度算法是一种经典的时间片轮转算法,每个进程在给定的时间片内依次执行一定数量的时间。
如果进程的执行时间超过时间片,进程将被暂时挂起,等待下一次轮转。
在本实验中,我们使用C语言编写代码模拟Round Robin算法的调度过程,并计算每个进程的等待时间、周转时间和响应时间。
4. 实验结果分析通过对不同调度算法的模拟实验结果进行分析,可以得出以下结论:- FCFS算法适用于任务到达的先后顺序不重要的场景,但对于执行时间较长的进程可能会导致下一个进程需要等待较久。
- SJF算法适用于任务的执行时间差异较大的场景,能够提高整体执行效率。
- Round Robin算法适用于时间片相对较小的情况,能够公平地为每个进程提供执行时间。
5. 实验总结本次实验通过模拟不同调度算法的实际执行过程,深入了解了各种调度算法的原理、特点和适用场景。
通过对实验结果的分析,我们可以更好地选择合适的调度算法来满足实际应用的需求。
在后续的学习中,我们将进一步探索更多操作系统相关的实验和算法。
算法分析与设计实验报告:合并排序与快速排序一、引言算法是计算机科学中非常重要的一部分,它涉及到解决问题的方法和步骤。
合并排序和快速排序是两种经典而常用的排序算法。
本文将对这两种排序算法进行分析和设计实验,通过对比它们的性能和效率,以期得出最优算法。
二、合并排序合并排序是一种分治算法,它将原始数组不断分解为更小的数组,直到最后细分为单个元素。
然后,再将这些单个元素两两合并,形成一个有序数组。
合并排序的核心操作是合并两个有序的数组。
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. 实验目的:比较合并排序和快速排序的时间复杂度和空间复杂度。
FFT算法分析实验实验报告一、实验目的快速傅里叶变换(Fast Fourier Transform,FFT)是数字信号处理中一种非常重要的算法。
本次实验的目的在于深入理解 FFT 算法的基本原理、性能特点,并通过实际编程实现和实验数据分析,掌握 FFT 算法在频谱分析中的应用。
二、实验原理FFT 算法是离散傅里叶变换(Discrete Fourier Transform,DFT)的快速计算方法。
DFT 的定义为:对于长度为 N 的序列 x(n),其 DFT 为X(k) =∑n=0 到 N-1 x(n) e^(j 2π k n / N) ,其中 j 为虚数单位。
FFT 算法基于分治法的思想,将 N 点 DFT 分解为多个较小规模的DFT,从而大大减少了计算量。
常见的 FFT 算法有基 2 算法、基 4 算法等。
三、实验环境本次实验使用的编程语言为 Python,主要依赖 numpy 库来实现 FFT 计算和相关的数据处理。
四、实验步骤1、生成测试信号首先,生成一个包含不同频率成分的正弦波叠加信号,例如100Hz、200Hz 和 300Hz 的正弦波。
设定采样频率为 1000Hz,采样时间为 1 秒,以获取足够的采样点进行分析。
2、进行 FFT 计算使用 numpy 库中的 fft 函数对生成的测试信号进行 FFT 变换。
3、频谱分析计算 FFT 结果的幅度谱和相位谱。
通过幅度谱确定信号中各个频率成分的强度。
4、误差分析与理论上的频率成分进行对比,计算误差。
五、实验结果与分析1、幅度谱分析观察到在 100Hz、200Hz 和 300Hz 附近出现明显的峰值,对应于生成信号中的频率成分。
峰值的大小反映了相应频率成分的强度。
2、相位谱分析相位谱显示了各个频率成分的相位信息。
3、误差分析计算得到的频率与理论值相比,存在一定的误差,但在可接受范围内。
误差主要来源于采样过程中的量化误差以及 FFT 算法本身的近似处理。
第1篇一、实验背景随着信息技术的飞速发展,计算课已成为现代教育中不可或缺的一部分。
通过计算课的学习,学生可以掌握计算机基本操作、编程语言以及算法设计等知识,为今后从事相关工作奠定基础。
本次实验旨在通过实际操作,加深对所学知识的理解,提高动手能力和团队协作能力。
二、实验目的1. 熟悉计算机基本操作,掌握常用软件的使用方法;2. 学习一种编程语言,理解编程思想,实现基本算法;3. 培养团队协作精神,提高动手实践能力;4. 提高对计算课重要性的认识,激发学习兴趣。
三、实验内容本次实验主要包括以下内容:1. 计算机基本操作:熟练使用计算机操作系统,掌握文件管理、系统设置等基本操作;2. 编程语言学习:选择一种编程语言(如Python、Java等),学习基本语法、数据结构、算法等知识;3. 算法实现:设计并实现一个简单算法,如排序、查找等;4. 项目实践:分组完成一个小型项目,如制作一个简单的网页、编写一个计算器程序等。
四、实验过程1. 实验准备:了解实验内容,预习相关理论知识,准备好实验所需的计算机和软件;2. 实验操作:按照实验指导书进行操作,记录实验步骤和结果;3. 团队协作:分组讨论,分工合作,共同完成实验任务;4. 结果分析:对实验结果进行分析,总结经验教训。
五、实验结果与分析1. 计算机基本操作:通过实验,掌握了计算机基本操作,如文件管理、系统设置等,提高了计算机应用能力;2. 编程语言学习:学习了所选编程语言的基本语法、数据结构、算法等知识,为今后深入学习打下了基础;3. 算法实现:实现了排序、查找等基本算法,加深了对算法原理的理解;4. 项目实践:分组完成了一个小型项目,如制作了一个简单的网页、编写了一个计算器程序等,提高了团队协作能力和动手实践能力。
六、实验总结1. 计算课实验对提高学生计算机应用能力具有重要意义,有助于培养学生动手实践能力和团队协作精神;2. 实验过程中,要注重理论与实践相结合,不断总结经验教训,提高实验效果;3. 在今后的学习中,要继续努力,深入学习计算课相关知识,为将来从事相关工作打下坚实基础。
题目: a算法求解八数码问题实验报告目录1. 实验目的2. 实验设计3. 实验过程4. 实验结果5. 实验分析6. 实验总结1. 实验目的本实验旨在通过实验验证a算法在求解八数码问题时的效果,并对其进行分析和总结。
2. 实验设计a算法是一种启发式搜索算法,主要用于在图形搜索和有向图中找到最短路径。
在本实验中,我们将使用a算法来解决八数码问题,即在3x3的九宫格中,给定一个初始状态和一个目标状态,通过移动数字的方式将初始状态转变为目标状态。
具体的实验设计如下:1) 实验工具:我们将使用编程语言来实现a算法,并结合九宫格的数据结构来解决八数码问题。
2) 实验流程:我们将设计一个初始状态和一个目标状态,然后通过a 算法来求解初始状态到目标状态的最短路径。
在求解的过程中,我们将记录下每一步的状态变化和移动路径。
3. 实验过程我们在编程语言中实现了a算法,并用于求解八数码问题。
具体的实验过程如下:1) 初始状态和目标状态的设计:我们设计了一个初始状态和一个目标状态,分别为:初始状态:1 2 34 5 67 8 0目标状态:1 2 38 0 42) a算法求解:我们通过a算法来求解初始状态到目标状态的最短路径,并记录下每一步的状态变化和移动路径。
3) 实验结果在实验中,我们成功求解出了初始状态到目标状态的最短路径,并记录下了每一步的状态变化和移动路径。
具体的实验结果如下:初始状态:1 2 34 5 67 8 0目标状态:1 2 38 0 47 6 5求解路径:1. 上移1 2 37 8 62. 左移1 2 3 4 0 5 7 8 63. 下移1 2 3 4 8 5 7 0 64. 右移1 2 3 4 8 5 0 7 65. 上移1 2 3 0 8 5 4 7 61 2 38 0 54 7 67. 下移1 2 38 7 54 0 68. 右移1 2 38 7 54 6 0共计8步,成功从初始状态到目标状态的最短路径。
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告课程名称:算法设计与分析班级:软件101 实验日期:2012-10-23 姓名:学号:指导教师:实验序号:一实验成绩:一、实验名称分治算法实验- 棋盘覆盖问题二、实验目的及要求1、熟悉递归算法编写;2、理解分治算法的特点;3、掌握分治算法的基本结构。
三、实验环境Visual C++四、实验内容根据教材上分析的棋盘覆盖问题的求解思路,进行验证性实验;要求完成棋盘覆盖问题的输入、分治求解、输出。
有余力的同学尝试消去递归求解。
五、算法描述及实验步骤分治算法原理:分治算法将大的分解成形状结构相同的子问题,并且不断递归地分解,直到子问题规模小到可以直接求解。
棋盘覆盖问题描述:在一个2k x 2k个方格组成的棋盘中恰有一个方格与其他的不同称为特殊方格,想要求利用四种L型骨牌(每个骨牌可覆盖三个方格)不相互重叠覆盖的将除了特殊方格外的其他方格覆盖。
实验步骤:1、定义用于输入和输出的数据结构;2、完成分治算法的编写;3、测试记录结构;4、有余力的同学尝试不改变输入输出结构,将递归消除,并说明能否不用栈,直接消除递归,为什么?六、调试过程及实验结果详细记录程序在调试过程中出现的问题及解决方法。
记录程序执行的结果。
七、总结对上机实践结果进行分析,问题回答,上机的心得体会及改进意见。
通过对本实验的学习,对分治算法有了进一步的认识,对棋盘覆盖问题和其他分治问题进行了对比。
八、附录源程序(核心代码)清单或使用说明书,可另附纸①#include<iostream>#include<cmath>using namespace std;int board[100][100],tile=1;void chessboard(int tr,int tc,int dr,int dc,int size)//tr 棋盘左上角方格的行号,tc棋盘左上角方格的列号。
dr特殊方格所在的行号。
dc特殊方格所在的列号。
size棋盘的大小2^k.{int s;if(size==1)return ;int t=tile++;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); }}int main(){int k,tr,tc,size,i,j;cin>>k>>tr>>tc;size=pow(2,k);chessboard(0,0,tr,tc,size);for(i=0;i<size;i++){for(j=0;j<size;j++)cout<<board[i][j]<<" ";cout<<endl;}return 0;}贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告课程名称:算法设计与分析班级:软件101 实验日期:2012-11-6姓名:学号:指导教师:实验序号:二实验成绩:一、实验名称动态规划实验- 滑雪问题二、实验目的及要求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、构造算法框架①首先定义一个状态转移函数,用来遍历搜索所需的最长路径int DP(int i,int j){...}②在主函数中调用DP(i,j)函数,将所求最长路径的存放在变量ans中int main(){...}3、分析出算法复杂度因为DP(int i,int j)函数每调用一次,都要对i,j周围的四个数进行比较,这样的工作要重复进行,故需要O(n2)的时间。
六、调试过程及实验结果详细记录程序在调试过程中出现的问题及解决方法。
记录程序执行的结果。
输入5行5列数,结果如下:七、总结对上机实践结果进行分析,问题回答,上机的心得体会及改进意见。
通过本实验的学习,我对递归算法有了进一步的了解,在验证试验结果时,首先输入5行5列的数组大小和数据,主函数调用DP(int i,int j)函数,求出最长的路径;该算法的在时间复杂度上得进一步改进,如果对于大一点的数据,遍历效率就不高了。
八、附录源程序(核心代码)清单或使用说明书,可另附纸#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int M = 110;int a[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};int dp[M][M];int map[M][M];int ans,tmp;int R,C;int DP(int i,int j){if(dp[i][j] > 0)return dp[i][j];for(int k = 0; k < 4; k++){if( (i+a[k][0] >= 1) && (i+a[k][0] <= R) && (j+a[k][1] <= C) &&(j+a[k][1] >=1) && map[ i+a[k][0] ][j+a[k][1] ] < map[i][j] ){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;}}return dp[i][j];}int main(){int i;memset(dp,0,sizeof(dp));cin >> R >>C;for(i = 1; i <= R; i++)for(int j = 1; j <= C; j++)scanf("%d",&map[i][j]);for(i = 1; i <= R; i++)for(int j = 1; j <= C; j++){int aa = DP(i,j);if(ans < aa)ans = aa;}cout << ans + 1<<endl;return 0;贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告课程名称:算法设计与分析班级:软件101 实验日期:2012-10-20姓名:学号:1008060028 指导教师:实验序号:三实验成绩:一、实验名称贪心算法实验- 包装问题二、实验目的及要求1、使用在线测评的算法题目评分系统来测试所写代码;2、通过直观的应用问题,加深对贪心算法的理解;三、实验环境任意C或C++编写调试工具,北京大学ICPC在线测评系统POJ四、实验内容1、登陆POJ系统,找到题号为1017的题目-包装;2、阅读题目,分析出求解该问题的思路;3、使用贪心算法,实现本题;4、进行简单测试,完成之后提交到POJ系统。
五、算法描述及实验步骤贪心算法原理:贪心算法通过一系列的选择来达到子问题的解。
它所做的每一步选择都是当前状态下局部最好选择,即贪心选择。
这种启发式的策略虽不能总是奏效,但大多数情况下确能达到预期目的,得到最优解。
要使用贪心算法,问题必须具备两个基本要素。
贪心选择性质和最优子结构性质。
贪心选择性质指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。
通常采用自顶向下的方式进行,这样每做一次贪心选择就将所求问题化为规模更小的子问题。
当然,前提是所求问题本身的最优解包含其子问题的最优解,即具有最优子结构性质。