算法分析与设计作业及参考答案样本
算法设计与分析习题答案
算法设计与分析习题答案算法设计与分析是计算机科学中一个重要的领域,它涉及到算法的创建、优化以及评估。
以下是一些典型的算法设计与分析习题及其答案。
习题1:二分查找算法问题描述:给定一个已排序的整数数组,编写一个函数来查找一个目标值是否存在于数组中。
答案:二分查找算法的基本思想是将数组分成两半,比较中间元素与目标值的大小,如果目标值等于中间元素,则查找成功;如果目标值小于中间元素,则在左半部分继续查找;如果目标值大于中间元素,则在右半部分继续查找。
这个过程会不断重复,直到找到目标值或搜索范围为空。
```pythondef binary_search(arr, target):low, high = 0, len(arr) - 1while low <= high:mid = (low + high) // 2if arr[mid] == target:return Trueelif arr[mid] < target:low = mid + 1else:high = mid - 1return False```习题2:归并排序算法问题描述:给定一个无序数组,使用归并排序算法对其进行排序。
答案:归并排序是一种分治算法,它将数组分成两半,分别对这两半进行排序,然后将排序好的两半合并成一个有序数组。
```pythondef merge_sort(arr):if len(arr) > 1:mid = len(arr) // 2left_half = arr[:mid]right_half = arr[mid:]merge_sort(left_half)merge_sort(right_half)i = j = k = 0while i < len(left_half) and j < len(right_half): if left_half[i] < right_half[j]:arr[k] = left_half[i]i += 1else:arr[k] = right_half[j]j += 1k += 1while i < len(left_half):arr[k] = left_half[i]i += 1k += 1while j < len(right_half):arr[k] = right_half[j]j += 1k += 1arr = [38, 27, 43, 3, 9, 82, 10]merge_sort(arr)print("Sorted array is:", arr)```习题3:动态规划求解最长公共子序列问题问题描述:给定两个序列,找到它们的最长公共子序列。
算法分析与设计作业参考答案
算法分析与设计作业参考答案《算法分析与设计》作业参考答案作业⼀⼀、名词解释:1.递归算法:直接或间接地调⽤⾃⾝的算法称为递归算法。
2.程序:程序是算法⽤某种程序设计语⾔的具体实现。
⼆、简答题:1.算法需要满⾜哪些性质?简述之。
答:算法是若⼲指令的有穷序列,满⾜性质:(1)输⼊:有零个或多个外部量作为算法的输⼊。
(2)输出:算法产⽣⾄少⼀个量作为输出。
(3)确定性:组成算法的每条指令清晰、⽆歧义。
(4)有限性:算法中每条指令的执⾏次数有限,执⾏每条指令的时间也有限。
2.简要分析分治法能解决的问题具有的特征。
答:分析分治法能解决的问题主要具有如下特征:(1)该问题的规模缩⼩到⼀定的程度就可以容易地解决;(2)该问题可以分解为若⼲个规模较⼩的相同问题,即该问题具有最优⼦结构性质;(3)利⽤该问题分解出的⼦问题的解可以合并为该问题的解;(4)该问题所分解出的各个⼦问题是相互独⽴的,即⼦问题之间不包含公共的⼦问题。
3.简要分析在递归算法中消除递归调⽤,将递归算法转化为⾮递归算法的⽅法。
答:将递归算法转化为⾮递归算法的⽅法主要有:(1)采⽤⼀个⽤户定义的栈来模拟系统的递归调⽤⼯作栈。
该⽅法通⽤性强,但本质上还是递归,只不过⼈⼯做了本来由编译器做的事情,优化效果不明显。
(2)⽤递推来实现递归函数。
(3)通过Cooper 变换、反演变换能将⼀些递归转化为尾递归,从⽽迭代求出结果。
后两种⽅法在时空复杂度上均有较⼤改善,但其适⽤范围有限。
三、算法编写及算法应⽤分析题: 1.冒泡排序算法的基本运算如下: for i ←1 to n-1 dofor j ←1 to n-i do if a[j]交换a[j]、a[j+1];分析该算法的时间复杂性。
答:排序算法的基本运算步为元素⽐较,冒泡排序算法的时间复杂性就是求⽐较次数与n 的关系。
(1)设⽐较⼀次花时间1;(2)内循环次数为:n-i 次,(i=1,…n ),花时间为:∑-=-=in j i n 1)(1(3)外循环次数为:n-1,花时间为:2.设计⼀个分治算法计算⼀棵⼆叉树的⾼度。
算法设计与分析习题答案1-6章
习题11.图论诞生于七桥问题。
出生于瑞士的伟大数学家欧拉(Leonhard Euler ,1707—1783)提出并解决了该问题。
七桥问题是这样描述的:一个人是否能在一次步行中穿越哥尼斯堡(现在叫加里宁格勒,在波罗的海南岸)城中全部的七座桥后回到起点,且每座桥只经过一次,图1.7是这条河以及河上的两个岛和七座桥的草图。
请将该问题的数据模型抽象出来,并判断此问题是否有解。
七桥问题属于一笔画问题。
输入:一个起点 输出:相同的点 1, 一次步行2, 经过七座桥,且每次只经历过一次 3, 回到起点该问题无解:能一笔画的图形只有两类:一类是所有的点都是偶点。
另一类是只有二个奇点的图形。
2.在欧几里德提出的欧几里德算法中(即最初的欧几里德算法)用的不是除法而是减法。
请用伪代码描述这个版本的欧几里德算法 1.r=m-n2.循环直到r=0 2.1 m=n 2.2 n=r 2.3 r=m-n 3 输出m3.设计算法求数组中相差最小的两个元素(称为最接近数)的差。
要求分别给出伪代码和C ++描述。
//采用分治法//对数组先进行快速排序 //在依次比较相邻的差 #include <iostream> using namespace std;int partions(int b[],int low,int high) {图1.7 七桥问题int prvotkey=b[low];b[0]=b[low];while (low<high){while (low<high&&b[high]>=prvotkey)--high;b[low]=b[high];while (low<high&&b[low]<=prvotkey)++low;b[high]=b[low];}b[low]=b[0];return low;}void qsort(int l[],int low,int high){int prvotloc;if(low<high){prvotloc=partions(l,low,high); //将第一次排序的结果作为枢轴 qsort(l,low,prvotloc-1); //递归调用排序由low 到prvotloc-1qsort(l,prvotloc+1,high); //递归调用排序由 prvotloc+1到 high}}void quicksort(int l[],int n){qsort(l,1,n); //第一个作为枢轴,从第一个排到第n个}int main(){int a[11]={0,2,32,43,23,45,36,57,14,27,39};int value=0;//将最小差的值赋值给valuefor (int b=1;b<11;b++)cout<<a[b]<<' ';cout<<endl;quicksort(a,11);for(int i=0;i!=9;++i){if( (a[i+1]-a[i])<=(a[i+2]-a[i+1]) )value=a[i+1]-a[i];elsevalue=a[i+2]-a[i+1];}cout<<value<<endl;return 0;}4.设数组a[n]中的元素均不相等,设计算法找出a[n]中一个既不是最大也不是最小的元素,并说明最坏情况下的比较次数。
《算法分析与设计》课后作业
《算法分析与设计》各章课后作业第一章 课后作业1. 设某算法在输入规模为n 时的计算时间为T(n)=10*2n。
若在甲台计算机上实现并完成该算法的时间为t 秒,现有一台运行速度是甲的64倍的另一台计算机乙,问在乙计算机上用同一算法在t 秒内能解决的问题的规模是多大?2.按照渐近阶从低到高的顺序排列以下表达式:4n 2,logn ,3n,20n ,2,n 2/3。
又n!应该排在哪一位?第二章 课后作业1. 用展开法求解下列递推关系:T(n)=⎩⎨⎧>+=1n )()2/(20n )1(n O n T O,写出T(n)的大O 记号表示。
2. 下面是实现在a[0]<=a[1]<=…<=a[n-1]中搜索x 的二分搜索算法,请根据二分 搜索技术在下划线处填充语句。
算法描述如下: template<class Type>public static int BinarySearch(int []a, int x, int n) { //在a[0]<=a[1]<=…<=a[n-1]中搜索 x // 找到x 时返回其在数组中的位置,否则返回-1 int left = 0; int right = n - 1; while ( ) {int middle = ;if(x == a[middle]) return ; if(x > a[middle]) left = middle + 1; else right= ; }return -1; // 未找到x}第三章课后作业1、选择题。
(1)下列算法中通常以自底向上的方式求解最优解的是()。
A、备忘录法B、动态规划法C、贪心法D、回溯法(2)备忘录方法是那种算法的变形。
()A、分治法B、动态规划法C、贪心法D、回溯法(3)矩阵连乘问题的算法可由()设计实现。
A、分支界限算法B、动态规划算法C、贪心算法D、回溯算法2.计算题。
算法设计与分析+习题参考答案
算法设计与分析+习题参考答案5..证明等式gcd(m,n)=gcd(n,m mod n)对每⼀对正整数m,n都成⽴.Hint:根据除法的定义不难证明:●如果d整除u和v, 那么d⼀定能整除u±v;●如果d整除u,那么d也能够整除u的任何整数倍ku.对于任意⼀对正整数m,n,若d能整除m和n,那么d⼀定能整除n和r=m mod n=m-qn;显然,若d能整除n和r,也⼀定能整除m=r+qn和n。
数对(m,n)和(n,r)具有相同的公约数的有限⾮空集,其中也包括了最⼤公约数。
故gcd(m,n)=gcd(n,r)6.对于第⼀个数⼩于第⼆个数的⼀对数字,欧⼏⾥得算法将会如何处理?该算法在处理这种输⼊的过程中,上述情况最多会发⽣⼏次?Hint:对于任何形如0<=m并且这种交换处理只发⽣⼀次.7.a.对于所有1≤m,n≤10的输⼊, Euclid算法最少要做⼏次除法?(1次)b. 对于所有1≤m,n≤10的输⼊, Euclid算法最多要做⼏次除法?(5次)gcd(5,8)习题1.21.(农夫过河)P—农夫W—狼G—⼭⽺C—⽩菜2.(过桥问题)1,2,5,10---分别代表4个⼈, f—⼿电筒4. 对于任意实系数a,b,c, 某个算法能求⽅程ax^2+bx+c=0的实根,写出上述算法的伪代码(可以假设sqrt(x)是求平⽅根的函数)算法Quadratic(a,b,c)//求⽅程ax^2+bx+c=0的实根的算法//输⼊:实系数a,b,c//输出:实根或者⽆解信息D←b*b-4*a*cIf D>0temp←2*ax1←(-b+sqrt(D))/tempx2←(-b-sqrt(D))/tempreturn x1,x2else if D=0 return –b/(2*a)else return “no real roots”else //a=0if b≠0 return –c/belse //a=b=0if c=0 return “no real numbers”else return “no real roots”5.描述将⼗进制整数表达为⼆进制整数的标准算法a.⽤⽂字描述b.⽤伪代码描述解答:a.将⼗进制整数转换为⼆进制整数的算法输⼊:⼀个正整数n输出:正整数n相应的⼆进制数第⼀步:⽤n除以2,余数赋给Ki(i=0,1,2...),商赋给n第⼆步:如果n=0,则到第三步,否则重复第⼀步第三步:将Ki按照i从⾼到低的顺序输出b.伪代码算法DectoBin(n)//将⼗进制整数n转换为⼆进制整数的算法//输⼊:正整数n//输出:该正整数相应的⼆进制数,该数存放于数组Bin[1...n]中i=1while n!=0 do {Bin[i]=n%2;n=(int)n/2;i++;}while i!=0 do{print Bin[i];i--;}9.考虑下⾯这个算法,它求的是数组中⼤⼩相差最⼩的两个元素的差.(算法略) 对这个算法做尽可能多的改进.算法MinDistance(A[0..n-1])//输⼊:数组A[0..n-1]//输出:the smallest distance d between two of its elements习题1.31.考虑这样⼀个排序算法,该算法对于待排序的数组中的每⼀个元素,计算⽐它⼩的元素个数,然后利⽤这个信息,将各个元素放到有序数组的相应位置上去.a.应⽤该算法对列表‖60,35,81,98,14,47‖排序b.该算法稳定吗?c.该算法在位吗?解:a. 该算法对列表‖60,35,81,98,14,47‖排序的过程如下所⽰:b.该算法不稳定.⽐如对列表‖2,2*‖排序c.该算法不在位.额外空间for S and Count[]4.(古⽼的七桥问题)习题1.41.请分别描述⼀下应该如何实现下列对数组的操作,使得操作时间不依赖数组的长度. a.删除数组的第i 个元素(1<=i<=n)b.删除有序数组的第i 个元素(依然有序) hints:a. Replace the i th element with the last element and decrease the array size of 1b. Replace the ith element with a special symbol that cannot be a value of the array ’s element(e.g., 0 for an array of positive numbers ) to mark the i th position is empty. (―lazy deletion ‖)第2章习题2.17.对下列断⾔进⾏证明:(如果是错误的,请举例) a. 如果t(n )∈O(g(n),则g(n)∈Ω(t(n)) b.α>0时,Θ(αg(n))= Θ(g(n)) 解:a. 这个断⾔是正确的。
算法分析与设计试题及答案
算法分析与设计试题及答案一、选择题1. 下列哪个是属于分治算法的例子?A. 冒泡排序B. 归并排序C. 顺序查找D. 选择排序答案:B2. 在排序算法中,时间复杂度最优的是:A. 冒泡排序B. 插入排序C. 归并排序D. 快速排序答案:C3. 哪个不是动态规划的特点?A. 具有重叠子问题B. 通过递归求解C. 需要保存子问题的解D. 具有最优子结构答案:B4. 在图的广度优先搜索算法中,使用的数据结构是:A. 栈B. 队列C. 数组D. 堆栈答案:B5. 在最小生成树算法中,下列哪个不属于贪心策略?A. Kruskal算法B. Prim算法C. Dijkstra算法D. Prim-Kruskal混合算法答案:C二、简答题1. 请简述分治算法的思想和应用场景。
答案:分治算法的思想是将原问题分解成若干个规模较小且类似的子问题,然后解决子问题,最后将子问题的解合并得到原问题的解。
其应用场景包括排序算法(如归并排序、快速排序)、搜索算法(如二分查找)等。
2. 什么是动态规划算法?请给出一个动态规划算法的示例。
答案:动态规划算法是一种通过将问题分解成子问题并解决子问题来解决复杂问题的方法。
它的特点是具有重叠子问题和最优子结构性质。
以斐波那契数列为例,可以使用动态规划算法求解每一项的值,而不需要重复计算。
3. 图的深度优先搜索和广度优先搜索有什么区别?答案:图的深度优先搜索(Depth First Search,DFS)是一种先访问子节点再访问兄弟节点的遍历算法,通常使用递归或者栈实现。
而广度优先搜索(Breadth First Search,BFS)则是以层次遍历的方式展开搜索,使用队列来实现。
DFS更适合用于搜索路径,BFS则适用于寻找最短路径等。
4. 请简述贪心算法的特点及其应用场景。
答案:贪心算法的特点是每一步都采取当前状态下最优的选择,以期望得到全局最优解。
然而,贪心算法并不一定能求解所有问题的最优解,但对于一些特定问题,贪心算法往往能得到近似最优解。
算法设计与分析(王多强)作业参考答案.docx
第二章递归习题导论4.1-17(/?) = 27(b / 2)+ 1=> M = 2T5 /2) + 1%)习题导论4.1-6Tin) = 2T(0) + 1做代换:m=log2n另 S(m)=T(2m )则有: S(/z?) = 2S(zz? / 2) + 1 化简有:S(m)=O(m) 所以 T(n)=O(logn)习题4.2-27(/7)= T(n / 3) + 7(2/7 / 3) + 劲 注意最长分支 2n/3-*(2n/3)2 -*(2n/3)3...-*(2n^)log3/2n 习题4.3-1a) T(n) = 4T(n/2) + nb) T(n) = 4T(n/2) + n 2c 取大于1/2小于1的数即可,如珈习题4.3-4f(n )/nlogba = n 2log n/n'°g"二 log nvn所以不满足规则3直接化简即可,T(n)=O(n 2log 2n)c) T(n) = 4T(n/2) + n 3情况 3, ◎ (r?). 验证 4f(n/2)=4(n/2)3=n 3/2^cn 3,这里7X2")27(2"/彳)+情况4 0(n 2)情况 2, © (n 2logn)第三章习题4.5注意三分Z—和三分Z二分割点的计算ml = (2low+high)^m2 = (low+2high)/3习题4.20主要是验证T(n/r) + T(0)>|« n/r+O的数量级是否小于n的1次方(线性) 利用关系式:\n / r」n (/7 - r - 1) / /进行化简r=3:\r / 2~|~|_/2 / /_] / 2~| > 2 z? / r / 2 = n / r」> (/? 一2) / 3则,刀一卜/2北刀 / 厂」/ 2] < /? - (/? - 2) / 3 = 2/7 / 3 + 2 / 3 则,n〃 +羊n +厉超线性了r=7:\r / 2]\n / r\/ 2〕>/ 7」/2 = 2山 / 7」> 2(刀一6) / 7则,n - \r / i\\n / /」/ 2〕v 刀一2(刀一6) / 7 = 5刀 / 7 + 12 / 7可证,当n>48的时候,上式小于3伙则,n/7+3nA = 25n/28 <n 成立r=9:\r / 2][n / 厂」/ 2〕> 5[刀 / 9」/ 2 = (5 / 2)^/9」> 5(刀-8)/18n一\r / 2\[n / /」/ 2〕< 13/?/18 + 40/18可证,当n>20的时候,上式小于7n/8 则,n/9+7n/8 = 71n/72 <n 成立r=ll习题4.25肓接带入验证即可棋盘覆盖问题角上用一个骨牌覆盖,认为构造有特殊方格的区域,然后在四个区域上递归求解即可第四章中位数中位数习题导论9-2A)比较明显。
算法分析与设计习题答案
算法分析与设计习题答案《算法分析与设计》期末复习题及答案⼀、简要回答下列问题:1.算法重要特性是什么?2.算法分析的⽬的是什么?3.算法的时间复杂性与问题的什么因素相关?4.算法的渐进时间复杂性的含义?5.最坏情况下的时间复杂性和平均时间复杂性有什么不同?6.简述⼆分检索(折半查找)算法的基本过程。
7.背包问题的⽬标函数和贪⼼算法最优化量度相同吗?8.采⽤回溯法求解的问题,其解如何表⽰?有什么规定?9.回溯法的搜索特点是什么?10.n皇后问题回溯算法的判别函数place的基本流程是什么?11.为什么⽤分治法设计的算法⼀般有递归调⽤?12.为什么要分析最坏情况下的算法时间复杂性?13.简述渐进时间复杂性上界的定义。
14.⼆分检索算法最多的⽐较次数?15.快速排序算法最坏情况下需要多少次⽐较运算?16.贪⼼算法的基本思想?17.回溯法的解(x1,x2,……x n)的隐约束⼀般指什么?18.阐述归并排序的分治思路。
19.快速排序的基本思想是什么。
20.什么是直接递归和间接递归?消除递归⼀般要⽤到什么数据结构?21.什么是哈密顿环问题?22.⽤回溯法求解哈密顿环,如何定义判定函数?23.请写出prim算法的基本思想。
参考答案:1. 确定性、可实现性、输⼊、输出、有穷性2. 分析算法占⽤计算机资源的情况,对算法做出⽐较和评价,设计出额更好的算法。
3. 算法的时间复杂性与问题的规模相关,是问题⼤⼩n的函数。
4.当问题的规模n趋向⽆穷⼤时,影响算法效率的重要因素是T(n)的数量级,⽽其他因素仅是使时间复杂度相差常数倍,因此可以⽤T(n)的数量级(阶)评价算法。
时间复杂度T(n)的数量级(阶)称为渐进时间复杂性。
5. 最坏情况下的时间复杂性和平均时间复杂性考察的是n固定时,不同输⼊实例下的算法所耗时间。
最坏情况下的时间复杂性取的输⼊实例中最⼤的时间复杂度:W(n) = max{ T(n,I) } , I∈Dn平均时间复杂性是所有输⼊实例的处理时间与各⾃概率的乘积和:A(n) =∑P(I)T(n,I) I∈Dn6. 设输⼊是⼀个按⾮降次序排列的元素表A[i:j] 和x,选取A[(i+j)/2]与x⽐较,如果A[(i+j)/2]=x,则返回(i+j)/2,如果A[(i+j)/2]回溯法的搜索特点是什么7. 不相同。
算法分析与设计作业及参考答案
算法分析与设计作业及参考答案作业题目1、请分析冒泡排序算法的时间复杂度和空间复杂度,并举例说明其在实际中的应用场景。
2、设计一个算法,用于在一个未排序的整数数组中找到第二大的元素,并分析其时间复杂度。
3、比较贪心算法和动态规划算法的异同,并分别举例说明它们在解决问题中的应用。
参考答案1、冒泡排序算法时间复杂度:冒泡排序的基本思想是通过相邻元素的比较和交换,将最大的元素逐步“浮”到数组的末尾。
在最坏情况下,数组完全逆序,需要进行 n 1 轮比较和交换,每一轮比较 n i 次(i 表示当前轮数),所以总的比较次数为 n(n 1) / 2,时间复杂度为 O(n^2)。
在最好情况下,数组已经有序,只需要进行一轮比较,时间复杂度为 O(n)。
平均情况下,时间复杂度也为 O(n^2)。
空间复杂度:冒泡排序只在原数组上进行操作,不需要额外的存储空间,空间复杂度为 O(1)。
应用场景:冒泡排序算法简单易懂,对于规模较小的数组,或者对算法的简单性要求较高而对性能要求不是特别苛刻的场景,如对少量数据进行简单排序时,可以使用冒泡排序。
例如,在一个小型的学生成绩管理系统中,需要对一个班级的少量学生成绩进行排序展示,冒泡排序就可以满足需求。
2、找到第二大元素的算法以下是一种使用遍历的方法来找到未排序整数数组中第二大元素的算法:```pythondef find_second_largest(arr):largest = arr0second_largest = float('inf')for num in arr:if num > largest:second_largest = largestlargest = numelif num > second_largest and num!= largest:second_largest = numreturn second_largest```时间复杂度分析:这个算法需要遍历数组一次,所以时间复杂度为O(n)。
《算法分析与设计》练习题一答案.docx
《算法分析与设计》练习题一答案1.程序书写格式应该遵循哪四个原则?参考答案:(1)正确使用缩进:一定要有缩进,否则代码的层次不明显。
(2)在一行内只写一条语句。
(3), '}'位置不可随意放置。
(4)变量和运算符之间最好加1个空格2.什么是算法?参考答案:用计算机解决问题的过程可以分成三个阶段:分析问题、设计算法和实现算法。
算法可以理解为冇基本运算及规定的运算顺序所构成的完整的解题步骤,它是求解问题类的、机械的、统一的方法,它由有限多个步骤组成,对于问题类屮每个给定的具体问题,机械地执行这些步骤就可以得到问题的解答。
或者看成按照要求设计好的有限的确切的计算序列,并且这样的步骤和序列可以解决一类问题。
3.什么是线性结构?什么是非线性结构?参考答案:线性结构:数据逻辑结构屮的一类。
它的特征是若结构为非空集,则该结构有且只有一个开始结点和一个终端结点,并且所冇结点都冇R只冇一个直接前趋和一个直接后继。
线性表就是一个典型的线性结构。
栈、队列、串等都是线性结构。
非线性结构:数据逻辑结构中的另一大类,它的逻辑特征是一个结点可能有多个直接而趋和直接后继。
数组、广义表、树和图等数据结构都是非线性结构。
4.已知二叉树后序遍丿力序列是DABEC,屮序遍丿力序列是DEBAC,则前序遍历序列是什么?参考答案:前序遍历序列是CEDBA5.什么是数制?参考答案:数制是人们利用符号进行计数的一种科学方法。
数制也称计数制,是用一组固定的符号和统一的规则來表示数值的方法。
6.如果将十进制数106转换为八进制数,结果是多少?参考答案:1527.请问查找算法的效率用什么进行度量?参考答案:平均查找长度ASL:在查找其关键字等于给定值的过程小,需要和给定值进行比较的关键字个数的期望值称为查找成功吋的平均查找长度。
AS厶=£皿/=1其屮,n是结点的个数;是杳找第i个结点的概率,是找到第i个结点所需要的比较次数。
算法分析与设计(习题答案)
算法分析与设计教程习题解答第1章 算法引论1. 解:算法是一组有穷的规则,它规定了解决某一特定类型问题的一系列计算方法。
频率计数是指计算机执行程序中的某一条语句的执行次数。
多项式时间算法是指可用多项式函数对某算法进行计算时间限界的算法。
指数时间算法是指某算法的计算时间只能使用指数函数限界的算法。
2. 解:算法分析的目的是使算法设计者知道为完成一项任务所设计的算法的优劣,进而促使人们想方设法地设计出一些效率更高效的算法,以便达到少花钱、多办事、办好事的经济效果。
3. 解:事前分析是指求出某个算法的一个时间限界函数(它是一些有关参数的函数);事后测试指收集计算机对于某个算法的执行时间和占用空间的统计资料。
4. 解:评价一个算法应从事前分析和事后测试这两个阶段进行,事前分析主要应从时间复杂度和空间复杂度这两个维度进行分析;事后测试主要应对所评价的算法作时空性能分布图。
5. 解:①n=11; ②n=12; ③n=982; ④n=39。
第2章 递归算法与分治算法1. 解:递归算法是将归纳法的思想应用于算法设计之中,递归算法充分地利用了计算机系统内部机能,自动实现调用过程中对于相关且必要的信息的保存与恢复;分治算法是把一个问题划分为一个或多个子问题,每个子问题与原问题具有完全相同的解决思路,进而可以按照递归的思路进行求解。
2. 解:通过分治算法的一般设计步骤进行说明。
3. 解:int fibonacci(int n) {if(n<=1) return 1;return fibonacci(n-1)+fibonacci(n-2); }4. 解:void hanoi(int n,int a,int b,int c) {if(n>0) {hanoi(n-1,a,c,b); move(a,b);hanoi(n-1,c,b,a); } } 5. 解:①22*2)(−−=n n f n② )log *()(n n n f O =6. 解:算法略。
《算法分析与设计》作业答案
《算法分析与设计》作业1、考虑,10≤≤i x 而不是x i ∈{0,1}的连续背包问题。
一种可行的贪婪策略是:按价值密度非递减的顺序检查物品,若剩余容量能容下正在考察的物品,将其装入;否则,往背包内装如此物品的一部分。
(a) 对于n=3,w=[100,10,10],p=[20,15,15],以及c=105,上述装入法获得结果是什么?(b)证明这种贪婪算法总能获得最优解。
(c) 用伪代码描述此算法。
答:(a )利用贪婪算法,按价值密度考察的背包为w2,w3,w1;背包w2和w3重20,还可以容纳85,由于10≤≤i x ,背包w1还可以装入x1=0.85,则背包内物品总价值为15+15+20*0.85=47.(b )假设已按价值密度排好序,考察w1,w2,……,wi ,……,对应的价值为p1,p2,……,pi,……如果装到pi-1再装pi 时,恰好要取xi 个wi 。
(,10≤≤i x ) 因为比它价值密度大的都已装载完,所以此时获得的为最优解。
(c )算法描述如下: template <class T>int ContainerLoading( int x[], T w[], T c, int n ) {int *t = new int[n+1]; IndirectSort(w, t, n); for( int i=1; i<=n; i++) x[i] = 0;for(i=1; i<=n && w[t[i]]<=c; i++){ x[t[i]] = 1; c += w[t[i]]; } delete []t; }2、证明当且仅当二分图没有覆盖时,下述算法找不到覆盖。
m=0; //当前覆盖的大小对于A中的所有i,New[i]=Degree[i]对于B中的所有i,Cov[i]=falsewhile(对于A中的某些i,New[i]>0) {设v是具有最大的New[i]的顶点;C[m++]=v;for(所有邻接于v的顶点j) {If(!Cov[j]) {Cov[j] = true;对于所有邻接于j的顶点,使其New[k]减1}}}if (有些顶点未被覆盖) 失败else 找到一个覆盖2)给出一个具有覆盖的二分图,使得上述算法找不到最小覆盖。
算法设计与分析书后参考答案
参考答案第1章一、选择题1. C2. A3. C4. C A D B5. B6. B7. D 8. B 9. B 10. B 11. D 12. B二、填空题1. 输入;输出;确定性;可行性;有穷性2. 程序;有穷性3. 算法复杂度4. 时间复杂度;空间复杂度5. 正确性;简明性;高效性;最优性6. 精确算法;启发式算法7. 复杂性尽可能低的算法;其中复杂性最低者8. 最好性态;最坏性态;平均性态9. 基本运算10. 原地工作三、简答题1. 高级程序设计语言的主要好处是:(l)高级语言更接近算法语言,易学、易掌握,一般工程技术人员只需要几周时间的培训就可以胜任程序员的工作;(2)高级语言为程序员提供了结构化程序设计的环境和工具,使得设计出来的程序可读性好,可维护性强,可靠性高;(3)高级语言不依赖于机器语言,与具体的计算机硬件关系不大,因而所写出来的程序可移植性好、重用率高;(4)把复杂琐碎的事务交给编译程序,所以自动化程度高,发用周期短,程序员可以集中集中时间和精力从事更重要的创造性劳动,提高程序质量。
2. 使用抽象数据类型带给算法设计的好处主要有:(1)算法顶层设计与底层实现分离,使得在进行顶层设计时不考虑它所用到的数据,运算表示和实现;反过来,在表示数据和实现底层运算时,只要定义清楚抽象数据类型而不必考虑在什么场合引用它。
这样做使算法设计的复杂性降低了,条理性增强了,既有助于迅速开发出程序原型,又使开发过程少出差错,程序可靠性高。
(2)算法设计与数据结构设计隔开,允许数据结构自由选择,从中比较,优化算法效率。
(3)数据模型和该模型上的运算统一在抽象数据类型中,反映它们之间内在的互相依赖和互相制约的关系,便于空间和时间耗费的折衷,灵活地满足用户要求。
(4)由于顶层设计和底层实现局部化,在设计中出现的差错也是局部的,因而容易查找也容易纠正,在设计中常常要做的增、删、改也都是局部的,因而也都容易进行。
算法分析与设计作业
算法分析与设计作业
一、冒泡排序
1.1冒泡排序算法
冒泡排序(Bubble Sort)也称为沉底排序,算法的特点是从数组头
部到尾部进行多次遍历,当遍历到一些数时,如果比它前面的数大就交换。
比较 n 个数大小,可以进行 n-1 次交换。
冒泡排序的时间复杂度为
O(n^2),空间复杂度为O(1)。
算法步骤如下:
(1)比较相邻的元素,如果第一个比第二个大,就交换他们两个的
位置;
(2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后
一对,这样在最后循环结束时,最大的数会移动到最后;
(3)重复第一步,直到所有元素排序完成。
1.2冒泡排序算法的优化
冒泡排序的时间复杂度为O(n^2),为提高算法的速度,可以对冒泡
排序算法进行优化。
算法在每一轮排序后会判断是否有可以交换的数据,如果没有就表明
已经全部排序完成,此时可以终止排序。
相比传统的算法,优化后的算法可以大大减少不必要的循环,提高排
序的速度。
二、快速排序
2.1快速排序算法
快速排序(Quick Sort)是一种分治策略,将大问题分解为小问题,同时在排序过程中不断的拆分问题,最终完成排序。
快速排序的时间复杂度为O(nlogn),空间复杂度为O(nlogn)。
算法步骤如下:。
算法分析与设计(参考题及答案
A、找出最优解的性质 B、构造最优解
C、算出最优解 D、定义最优解
答案:A
27.对完全二叉树自顶向下,从左向右给节点编号,节点编号为10的父节点编号为( ).
A、0 B、2 C、4 D、6
答案:C
28.下面哪种函数是回溯法中为避免无效搜索采取的策略()
3.贪婪技术并不能够总是找到最优解。
A、正确 B、错误 答案:正确
4.对于任何权重的图,Dijkstra算法总能产生一个正确的解。
A、正确 B、错误 答案:错误
5.对于给定的字符表及其出现的概率,哈夫曼编码是唯一的。
A、正确 B、错误 答案:错误
6.贪婪算法是在每一步中,“贪婪”地选择最佳操作,并希望通过一系列局部的最优选择, 能产生一个整个问题的最优解。
一、单选题 1.下列函数关系随着输入量增大增加最快的是( )
A、log2n B、n2 C、2n D、n!
答案:C
2.实现循环赛日程表利用的算法是()。
A、分治策略 B、动态规划法 C、贪心法 D、回溯法
答案:A
3.最长公共子序列算法利用的算法是()。
A、分支界限法 B、动态规划法 C、贪心法 D、回溯法
答案:某个问题的最优解包含着其子问题的最优解。这种性质称为最优子结构性质。
3.简述动态规划方法所运用的最优化原理。
答案:“最优化原理”用数学化的语言来描述:假设为了解决某一优化问题,需要依次作出n个决策D1,D2,…,Dn,如若这 个决策序列是最优的,对于任何一个整数k,1<k<n,不论前面k个决策是怎样的,以后的最优决策只取决于由前面决策所确定 的当前状态,即以后的决策Dk+1,Dk+2,…,Dn也是最优的。
算法设计与分析课后习题
算法设计与分析课后习题(总8页)--本页仅作为文档封面,使用时请直接删除即可----内页可以根据需求调整合适字体及大小--第一章1. 算法分析题算法分析题1-1 求下列函数的渐进表达式(1). 3n^2 + 10n < 3n^2 + 10n^2 = 13n^2 = O(n^2)(2). n^2 / 10 + 2^n当n>5是,n^2 < 2 ^n所以,当n >= 1时,n^2/10 < 2 ^n故: n^2/10 + 2^n < 2 ^n + 2^n = 2*2^n = O(2^n)(3). 21 + 1/n < 21 + 1 = 22 = O(1)(4). log(n^3)=3log(n)=O(log(n))(5). 10log(3^n) = (10log3)n = O(n)算法分析题1-6(1)因为:f(n)=log(n^2) = 2log(n); g(n) = log(n) + 5所以:f(n)=Θ(log(n)+5) =Θ(g(n))(2)因为:log(n) < √n ; f(n) = 2log(n); g(n)= √n所以:f(n) = O(g(n))(3)因为:log(n) < n; f(n) = n; g(n) = log(n^2) = 2log(n)所以;f(n) = Ω(g(n))(4)因为:f(n) = nlogn +n; g(n) = logn所以:f(n) =Ω(g(n))(5)因为: f(n) = 10; g(n) = log(10)所以:f(n) =Θ(g(n))(6)因为: f(n)=log^2(n); g(n) = log(n)所以: f(n) ==Ω(g(n))(7)因为: f(n) = 2^n < 100*2^n; g(n)=100n^2; 2^n > n ^2所以: f(n) = Ω(g(n))(8)因为:f(n) = 2^n; g(n) = 3 ^n; 2 ^n < 3 ^n所以: f(n) = O(g(n))习题1-9 证明:如果一个算法在平均情况下的计算时间复杂性为Θ(f(n)),该算法在最坏情况下所需的计算时间为Ω(f(n)).分析与解答:因此,Tmax(N) = Ω(Tavg(N)) = Ω(Θ(f(n)))=Ω(f(n)).第二章算法分析题2-3 设a[0:n-1]是已经排好序的数组。
算法设计与分析答案参考
算法设计与分析答案参考1、⽤Floyd 算法求下图每⼀对顶点之间的最短路径长度,计算矩阵D 0,D 1,D 2和D 3,其中D k [i, j]表⽰从顶点i 到顶点j 的不经过编号⼤于k 的顶点的最短路径长度。
解在每条边的矩阵⾏中依次加⼊顶点1,2,3,判断有⽆最短路径 2、设有n=2k 个运动员要进⾏循环赛,现设计⼀个满⾜以下要求的⽐赛⽇程表:①每个选⼿必须与其他n-1名选⼿⽐赛各⼀次;②每个选⼿⼀天⾄多只能赛⼀次;③循环赛要在最短时间内完成。
(1)如果n=2k ,循环赛最少需要进⾏⼏天;(2)当n=23=8时,请画出循环赛⽇程表。
解:(1)⾄少要进⾏n 天(2)如右图:3、对于下图使⽤Dijkstra 算法求由顶点a 到顶点h 的最短路径。
1 2 3 4 5 67 82 1 43 6 58 7解:⽤V 1表⽰已经找到最短路径的顶点,V 2表⽰与V 1中某个顶点相邻接且不在V 1中的顶点;E 1表⽰加⼊到最短路径中的边,E 2为与V 1中的顶点相邻接且距离最短的路径。
步骤 V 1 V 2 E 1E 2 1. {a}{b} {}{ab}2. {a,b} {d} {ab}{bd}3. {a,b,d}{c,f} {ab,bd}{dc,df} 4. {a,b,d,c} {f} {ab,bd}{df} 5. {a,b,c,d,f} {e} {ab,bd,dc,df}{fe}6. {a,b,c,d,e,f}{g} {ab,bd,dc,df,fe} {eg}7. {a,b,c,d,e,f,g} {h}{ab,bd,dc,df,fe,eg}{gh}8. {a,b,c,d,e,f,g,h} {} {ab,bd,de,df,fe,eg,gh} {} 结果:从a 到h 的最短路径为a b d fe g h →→→→→→,权值为18。
求所有顶点对之间的最短路径可以使⽤Dijkstra 算法,使其起始节点从a 循环到h ,每次求起始节点到其他节点的最短路径,最终可以求得所有顶点对之间的最短路径。
算法分析与设计李清勇课后习题答案样本
5-1凸多边形最优三角剖分问题//3d5 凸多边形最优三角剖分#include "stdafx.h"#include <iostream> using namespace std;const int N = 7;//凸多边形边数+1int weight[][N] = {{0,2,2,3,1,4},{2,0,1,5,2,3},{2,1,0,2,1,4},{3,5,2,0,6,2},{1,2,1,6,0,1},{4,3,4,2,1,0}};//凸多边形权int MinWeightTriangulation(int n,int **t,int **s);void Traceback(int i,int j,int **s);//构造最优解int Weight(int a,int b,int c);//权函数int main(){int **s = new int *[N];int **t = new int *[N];for(int i=0;i<N;i++) {s[i] = new int[N];t[i] = new int[N];}cout<<"此多边形最优三角剖分值为:"<<MinWeightTriangulation(N-1,t,s)<<endl;cout<<"最优三角剖分构造为:"<<endl;Traceback(1,5,s);//s[i][j]记录了Vi-1和Vj构成三角形第3个顶点位置return 0;}int MinWeightTriangulation(int n,int **t,int **s){for(int i=1;i<=n;i++){t[i][i] = 0;}for(int r=2;r<=n;r++) //r为当前计算链长(子问题规模){for(int i=1;i<=n-r+1;i++)//n-r+1为最后一种r链前边界{int j = i+r-1;//计算前边界为r,链长为r链后边界t[i][j] = t[i+1][j] + Weight(i-1,i,j);//将链ij划分为A(i) * ( A[i+1:j] )这里事实上就是k=i s[i][j] = i;for(int k=i+1;k<j;k++){//将链ij划分为( A[i:k] )* (A[k+1:j])int u = t[i][k] + t[k+1][j] + Weight(i-1,k,j);if(u<t[i][j]){t[i][j] = u;s[i][j] = k;}}}}return t[1][N-2];}void Traceback(int i,int j,int **s){if(i==j) return;Traceback(i,s[i][j],s);Traceback(s[i][j]+1,j,s);cout<<"三角剖分顶点:V"<<i-1<<",V"<<j<<",V"<<s[i][j]<<endl; }int Weight(int a,int b,int c){return weight[a][b] + weight[b][c] + weight[a][c];}5-4 数字三角形最短途径5-2 游艇租赁问题#include <iostream>using namespace std;#define N 210int cost[N][N];int m[N];int main(){int n,i,j;while(cin>>n){for(i=1;i<n;i++)for(j=i+1;j<=n;j++)cin>>cost[i][j];m[1]=0;int min;for(i=2;i<=n;i++){min=cost[1][i];for(j=1;j<=i-1;j++){if(cost[j][i]!=0 && m[j]+cost[j][i]<min)min=m[j]+cost[j][i];}m[i]=min;}cout<<m[n]<<endl;}return 0;}5-6 合唱队形问题#include <iostream>ing namespace std;2.3.//用于保存子问题最优解备忘录4.typedef struct5.{6.int maxlen; //当前子问题最优解7.int prev; //构造该子问题所用到下一级子问题序号(用于跟踪输出最优队列)8.}Memo;9.10.//用于递归输出Memo B中解11.void Display(int* A, Memo* M, int i)12.{13.if (M[i].prev == -1)14. {15. cout<<A[i]<<" ";16.return;17. }18. Display(A, M, M[i].prev);19. cout<<A[i]<<" ";20.}21.22.//算法重要某些23.void GetBestQuence(int* A, int n)24.{25.//定义备忘录并作必要初始化26. Memo *B = new Memo[n]; //B[i]代表从A[0]到A[i]满足升序剔除某些元素后能得到最多元素个数27. Memo *C = new Memo[n]; //C[i]代表从A[i]到A[n-1]满足降序剔除某些元素后能得到最多元素个数28. B[0].maxlen = 1; //由于B[i]由前向后构造初始化最前面子问题 (元素自身就是一种满足升序降序序列)29. C[n-1].maxlen = 1; //同样C[i]由后向前构造30.for (int i=0; i<n; i++) //为前一种最优子问题序号给定一种特殊标记-131.//用于在跟踪途径时终结递归或迭代(由于咱们并不懂得最后队列从哪里开始)32. {33. B[i].prev = -1;34. C[i].prev = -1;35. }36.37.for (i=1; i<n; i++) //构造B[n]38. {39.int max=1;40.for (int j=i-1; j>=0; j--) //查看前面子问题找出满足条件最优解并且记录41. {42.if (A[j]<A[i] && B[j].maxlen+1>max)43. {44. max = B[j].maxlen+1; //跟踪当前最优解45. B[i].prev = j; //跟踪构造途径46. }47. }48. B[i].maxlen = max; //构造最优解49. }50.51.for (i=n-1; i>0; i--)52. {53.int max=1;54.for (int j=i; j<n; j++) //从后往前构造这是为了背面在统筹最后解时可以直接用B[i]+C[i]-155.//否则咱们得到最优解始终为B[n-1]+C[n-1]56. {57.if (A[j]<A[i] && C[j].maxlen+1>max) //比当前长度更长记录并构造58. {59. max = C[j].maxlen+1;60. C[i].prev = j;61. }62. }63. C[i].maxlen = max;64. }65.66.//遍历i 得到最大B[i]+C[i]-1(-1是由于咱们在B[i]和C[i]中均加上了A[i]这个数因而需要减去重复)67.int maxQuence = 0; //记录当前最优解68.int MostTall; //记录i 用于跟踪构造途径69.for (i=0; i<n; i++)70. {71.if (B[i].maxlen+C[i].maxlen-1 > maxQuence)72. {73. maxQuence = B[i].maxlen+C[i].maxlen-1;74. MostTall = i;75. }76. }77.78. cout<<"最大合唱队形长度: "<<maxQuence<<endl;79.80.//B由前向后构造因而prev指向前面元素需要递归输出81. Display( A, B, MostTall);82.//Cprev指向背面元素直接迭代输出83.while (C[MostTall].prev != -1)84. {85. MostTall = C[MostTall].prev;86. cout<<A[MostTall]<<" ";87. }88. cout<<endl;89.90.delete []B;91.delete []C;92.}93.int main()94.{95.//测试96.int *A;97.int n;98. cout<<"请输入合唱队员个数: "<<endl;99. cin>>n;100.101. A = new int[n];102. cout<<"输入队员身高 :"<<endl;103.for (int i=0; i<n; i++)104. {105. cin>>A[i];106. }107. GetBestQuence(A, n);108.delete []A;109.return 0;110.}5-7买票问题状态转移方程是f[i] := min(f[i - 1] + t[i],f[i - 2] + r[i - 1]);{i = 2 ~ n} 初值f[0] := 0;f[1] := t[1];constmaxn = 1000;var i,j,n :longint;f,t,r :array[0..maxn] of longint;function min(a,b :longint) :longint;begin if a < b then exit(a);exit(b);end;beginreadln(n);for i := 1 to n do read(t[i]);for i := 1 to n - 1 do read(r[i]);f[0] := 0;f[1] := t[1];for i := 2 to n dof[i] := min(f[i - 1] + t[i],f[i - 2] + r[i - 1]);writeln(f[n]);end.伪代码BuyTicks(T,R)1n ← length[T]2 f[0] ← 03 f[1] ← T[1]4for i ← 2 to n do5f[i] ← f[i-2]+R[i-1]6if f[i] > f[i-1]+T[i] then 7f[i] ← f[i-1]+T[i]8return f5-8最大子段和问题#include <stdio.h>#include <malloc.h>int max_sum(int n,int *a,int *besti,int *bestj){ int *b = (int *)malloc(n * sizeof(int));int sum = 0;int i = -1;int temp = 0;for (i=0;i<=n-1;i++) {if (temp > 0)temp += a[i];elsetemp = a[i];b[i] = temp;}sum = b[0];for (i=1;i<=n-1;i++) {if (sum < b[i]) {sum = b[i];*bestj = i;}}for (i = *bestj;i >= 0;i--) {if (b[i] == a[i]) {*besti = i;break;}}free(b);return sum;}int main(void){int a[] = {-2,1,-4,13,-5,-2,-10,20,100};int length = sizeof(a)/sizeof(int);int sum = -1;int besti = -1;int bestj = -1;sum = max_sum(length,a,&besti,&bestj);printf("besti = %d,bestj = %d,max_sum=%d\n",besti,bestj,sum);return 0;}5-9 装箱问题发现就是0-1背包问题每个物品体积就是耗费同步也是价值,也就是说这题可以转化为在总体积为w下,可以得到最大价值最后用总体积减去最大价值就是剩余至少空间状态转移方程d[j] = max(d[j],d[j - a[i]] + a[i]);#include <stdio.h>#include <string.h>using namespace std;int n;int d[5];int a[35];int main(){int w;scanf("%d%d",&w,&n);int i,j;for(i = 0;i < n;i++){scanf("%d",&a[i]);}memset(d,0,sizeof(d));for(i = 0;i < n;i++){for(j = w;j >= a[i];j--)d[j] = max(d[j],d[j - a[i]] + a[i]);}printf("%d\n",w - d[w]);return0;}</algorithm></string.h></stdio.h> 6-10 表格乘法#include "stdio.h"#define num 50void chengji_1(int (*a)[num][3],int n,char b[]); int _tmain( ){int a[num][num][3];char b[num];int i,j,k,n;char c;printf("intput the num of array:");scanf("%d",&n);getchar();for(i=0;i<n;i++)for(j=0;j<n;j++)for(k=0;k<3;k++)a[i][j][k]=0;i=0;while((c=getchar())!='/n'){b[i]=c;i++;}chengji_1(a,n,b);printf("reslut is:%d",a[0][n-1][0]);getchar();}void chengji_1(int (*a)[num][3],int n,char b[]){int i,j,k,t;for(i=0;i<n;i++)*(*(*(a+i)+i)+(b[i]-'a'))=1;for(k=1;k<n;k++)for(i=0;i<n;i++){j=i+k;for(t=i;t<j;t++){*(*(*(a+i)+j)+0)+=((*(*(*(a+i)+t)+0))*(*(*(*(a+t+1)+j)+2))+(*(*(*(a+i)+t)+1))*(*(*(*(a+t+1)+j )+2))+(*(*(*(a+i)+t)+2))*(*(*(*(a+t+1)+j)+0)));*(*(*(a+i)+j)+1)+=((*(*(*(a+i)+t)+0))*(*(*(*(a+t+1)+j)+0))+(*(*(*(a+i)+t)+0))*(*(*(*(a+t+1)+j )+1))+(*(*(*(a+i)+t)+1))*(*(*(*(a+t+1)+j)+1)));*(*(*(a+i)+j)+2)+=((*(*(*(a+i)+t)+1))*(*(*(*(a+t+1)+j)+0))+(*(*(*(a+i)+t)+2))*(*(*(*(a+t+1)+j )+1))+(*(*(*(a+i)+t)+2))*(*(*(*(a+t+1)+j)+2)));} }}11 最长滑雪道问题#include <iostream>using namespace std;int data[102][102],longetr[102][102];int m,n;int cal(int i,int j){int max = 0;if (longetr[i][j] > 0)//如果该点已经计算过直接返回途径长度,保存已有计算成果这是动态规划优越之处return longetr[i][j];if(j-1 >= 0 && data[i][j] > data[i][j-1] && max < cal(i,j-1))max = cal(i,j-1);//向左走if(j+1 < n && data[i][j] > data[i][j+1] && max < cal(i,j+1))max = cal(i,j+1);//向右走if(i-1 >= 0 && data[i][j] > data[i-1][j] && max < cal(i-1,j))max = cal(i-1,j);//向上走if(i+1 < m && data[i][j] > data[i+1][j] && max < cal(i+1,j))max = cal(i+1,j);//向下走return longetr[i][j] = max + 1;//最长途径就是相邻四个节点最长途径加1所得四条途径中最长那条}int main(){int i,j;cin>>m>>n;int maxway = 0;for ( i=0;i<m;i++)for( j=0;j<n;j++){cin>>data[i][j];longetr[i][j] = 0;}for ( i=0;i<m;i++)for( j=0;j<n;j++){longetr[i][j] = cal(i,j);}for ( i=0;i<m;i++)for( j=0;j<n;j++){if(maxway < longetr[i][j])maxway = longetr[i][j];}cout<<maxway<<endl;return 0;}办法2 #include<iostream#include<cmath>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;struct dot//创立一种构造体存储每个点信息{int x;int y;int h;};dot line[0]; //将每个点存入该构造体数组int height[120][120]; //用于存储inputint len[120][120]; //dp数组,存储每个点最优解int cmp( const void *a ,const void *b) //迅速排序参照函数{if((*(dot *)a).h>(*(dot *)b).h)return 1;else return -1;}int main (){int m,n;cin>>m>>n;int i,j;int flag=-1;int max=0;for(i=1;i<=m;i++){for(j=1;j<=n;j++){flag++;scanf("%d",&height[i][j]);line[flag].x=i;line[flag].y=j;line[flag].h=height[i][j];}} //这个双层循环用来完毕数据收集工作qsort(line,m*n,sizeof(line[0]),cmp); //对构造体h参数进行排序for(i=0;i<m*n;i++){if(height[line[i].x][line[i].y]<height[line[i].x][line[i].y+1]&&len[line[i].x][line [i].y]>=len[line[i].x][line[i].y+1]){len[line[i].x][line[i].y+1]=len[line[i].x][line[i].y]+1;}if(height[line[i].x][line[i].y]<height[line[i].x+1][line[i].y]&&len[line[i].x][line [i].y]>=len[line[i].x+1][line[i].y]){len[line[i].x+1][line[i].y]=len[line[i].x][line[i].y]+1;}if(height[line[i].x][line[i].y]<height[line[i].x][line[i].y-1]&&len[line[i].x][line[ i].y]>=len[line[i].x][line[i].y-1]){len[line[i].x][line[i].y-1]=len[line[i].x][line[i].y]+1;}if (height[line[i].x][line[i].y]<height[line[i].x-1][line[i].y]&&len[line[i].x][li ne[i].y]>=len[line[i].x-1][line[i].y]){len[line[i].x-1][line[i].y]=len[line[i].x][line[i].y]+1;}} //动态规划过程for(i=1;i<=m;i++){for(j=1;j<=n;j++){if(len[i][j]>max)max=len[i][j];}} //遍历len数组,求出最大值cout<<max+1<<endl;// 由于初始值是0,因此最后要加一return 0;最大矩形和b[j]=max{b[j-1]+a[j],a[j]},1 #include <iostream>2 using namespace std;34 int ** a;5 int **sum;6 int max_array(int *a,int n)7 {8 int *c = new int [n];9 int i =0;10 c[0] = a[0];11 for(i=1;i<n;i++)12 {13 if(c[i-1]<0)14 c[i] = a[i];15 else16 c[i] = c[i-1]+a[i];17 }18 int max_sum = -65536;19 for(i=0;i<n;i++)20 if(c[i]>max_sum)21 max_sum = c[i];22 delete []c;23 return max_sum;2425 }26 int max_matrix(int n)27 {28 int i =0;30 int max_sum = -65535;31 int * b = new int [n];3233 for(i=0;i<n;i++)34 {35 for(j=0;j<n;j++)36 b[j]= 0;37 for(j=i;j<n;j++)//把数组从第i行到第j行相加起来保存在b中,在加时,自底向上,一方面计算行间隔(j-i)等于1状况,然后计算j-i等于2状况,一次类推,在小间隔基本上一次累加,避免重复计算38 {39 for(int k =0;k<=n;k++)40 b[k] += a[j][k];41 int sum = max_array(b,n);42 if(sum > max_sum)43 max_sum = sum;44 }45 }46 delete []b;47 return max_sum;48 }49 int main()50 {51 int n;5354 a = new int *[n];55 sum = new int *[n];56 int i =0;57 int j =0;58 for(i=0;i<n;i++)59 {60 sum[i] = new int[n];61 a[i] = new int[n];62 for(j=0;j<n;j++)63 {64 cin>>a[i][j];65 sum[i][j] =0 ;//sum[r][k]表达起始和结尾横坐标分别为r,k时最大子矩阵66 //sum[r][k] = max{sum (a[i][j]):r<=i<=k}:0<=k<=n-167 }68 }69 /*70 int b[10]={31,-41,59,26,-53,58,97,-93,-23,84};71 cout << max_array(b,10) << endl;72 */73 cout << max_matrix(n);74 }。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《算法分析与设计》作业( 一)
本课程作业由两部分组成。
第一部分为”客观题部分”, 由
15个选择题组成, 每题1分, 共15分。
第二部分为”主观题部分”,
由简答题和论述题组成, 共15分。
作业总分30分, 将作为平时成
绩记入课程总成绩。
客观题部分:
一、选择题( 每题1分, 共15题)
1、递归算法: ( C )
A、直接调用自身
B、间接调用自身
C、直接或间接
调用自身 D、不调用自身
2、分治法的基本思想是将一个规模为n的问题分解为k个规模
较小的字问题, 这些子问题: ( D )
A、相互独立
B、与原问题相同
C、相互依赖
D、相互独立且与原问题相同
3、备忘录方法的递归方式是:
( C )
A、自顶向下
B、自底向上
C、和动态规划算法相同
D、非递归的
4、回溯法的求解目标是找出解空间中满足约束条件的:
( A )
A、所有解
B、一些解
C、极大解
D、极小解
5、贪心算法和动态规划算法共有特点是: ( A )
A、最优子结构
B、重叠子问题
C、贪心选择
D、
形函数
6、哈夫曼编码是: ( B)
A、定长编码
B、变长编码
C、随机编码
D、定
长或变长编码
7、多机调度的贪心策略是: ( A)
A、最长处理时间作业优先
B、最短处理时间作业优
先
C、随机调度
D、最优调度
8、程序能够不满足如下性质: ( D )
A、零个或多个外部输入
B、至少一个输出
C、指令的确定性
D、指令的有限性
9、用分治法设计出的程序一般是: ( A )
A、递归算法
B、动态规划算法
C、贪心算法
D、回溯法
10、采用动态规划算法分解得到的子问题:
( C )
A、相互独立
B、与原问题相同
C、相互依赖
D、相互独立且与原问题相同
11、回溯法搜索解空间的方法是: ( A )
A、深度优先
B、广度优先
C、最小耗费优先
D、随机搜索
12、拉斯维加斯算法的一个显著特征是它所做的随机选性决策
有可能导致算法: ( C )
A、所需时间变化
B、一定找到解
C、找不到所需的解
D、性能变差
13、贪心算法能得到: ( C )
A、全局最优解
B、 0-1背包问题的解
C、背包问题的
解 D、无解
14、能求解单源最短路径问题的算法是: ( A )
A、分支限界法
B、动态规划
C、线形规划
D、蒙特卡罗算法
15、快速排序算法和线性时间选择算法的随机化版本是:
( A )
A、舍伍德算法
B、蒙特卡罗算法
C、拉斯维加斯算法
D、数值随机化算法
主观题部分:
二、写出下列程序的答案( 每题2.5分, 共2题)
1、请写出批处理作业调度的回溯算法。
#include<iostream>
#include<algorithm>
using namespace std;
class Flowing
{
friend int Flow(int ** ,int ,int []);
private:
//int Bound(int i);
void Backtrack(int t);
int **M;//
int *x;//当前解
int *bestx;//
int *f2;//
int f1;//
int f;//
int bestf;//
int n;//
};
void Flowing::Backtrack(int i)
{
if(i>n){
for(int j=1;j<=n;j++)
bestx[j]=x[j];
bestf=f;
}
else
for(int j=i;j<=n;j++){
f1+=M[x[j]][1];
f2[i]=((f2[i-1]>f1)?f2[i-1]:f1)+M[x[j]][2];
f+=f2[i];
if(f<bestf){
swap(x[i],x[j]);
Backtrack(i+1);
swap(x[i],x[j]);
}
f1-=M[x[j]][1];
f-=f2[i];
}
}
int Flow(int ** M,int n,int bestx[]){ int ub=INT_MAX;
Flowing X;
X.x=new int[n+1];
X.f2=new int[n+1];
X.M=M;
X.n=n;
X.bestx=bestx;
X.bestf=ub;
X.f1=0;
X.f=0;
for(int i=0;i<=n;i++)
X.f2[i]=0,X.x[i]=i;
X.Backtrack(1);
delete[] X.x;
delete[] X.f2;
return X.bestf;
}
void main(){
int **M;。