第4章 基本的算法策略(2011-10-10)

合集下载

基本的算法策略

基本的算法策略

任务分配问题就是在分配成本矩阵中的每一行 选取一个元素,这些元素分别属于不同的列, 选取一个元素,这些元素分别属于不同的列,并且 元素之和最小。 元素之和最小。
可以用一个n元组 可以用一个 元组(j1, j2, …, jn)来描述任务分配问题的一个可能 元组 来描述任务分配问题的一个可能 其中第i个分量 个分量j 行中选择的列号, 解,其中第 个分量 i(1≤i≤n)表示在第 行中选择的列号, ≤ ≤ )表示在第i行中选择的列号 因此用蛮力法解决任务分配问题要求生成整数1~n的全排列, 的全排列, 因此用蛮力法解决任务分配问题要求生成整数 的全排列 然后把成本矩阵中的相应元素相加来求得每种分配方案的总 成本,最后选出具有最小和的方案。 成本,最后选出具有最小和的方案。 序号 1 2 3 4 5 6 分配方案 1, 2, 3 1, 3, 2 2, 1, 3 2, 3, 1 3, 1, 2 3, 2, 1 总成本 9+4+1=14 9+3+8=20 2+6+1=9 2+3+5=10 7+6+8=21 7+4+5=16
证明0/1背包问题满足最优性原理。 证明 背包问题满足最优性原理。 背包问题满足最优性原理 是所给0/1背包问题的一个最优解 设(x1, x2, …, xn)是所给 背包问题的一个最优解,则 是所给 背包问题的一个最优解, ( x2, …, xn)是下面一个子问题的最优解: 是下面一个子问题的最优解: 是下面一个子问题的最优解
最优分配方案是将任务2 任务1 任务3 最优分配方案是将任务2,任务1,任务3分别分配给人 员1,人员2,人员3,将使总成本达到最小值9。 人员2 人员3 将使总成本达到最小值9

算法教学策略

算法教学策略

算法教学策略随着计算机的发展,算法成为计算科学的重要组成基础,算法思想已经成为现代人应具备的一种数学素养。

在世界上很多发达国家算法早已成为中学教学的重要内容。

我国2003年颁布了《高中数学课程标准》后,算法作为具体的教学内容进入中学数学的教科书中。

随着新课程实施的不断深入,算法“教与学”的有关问题逐渐被人们所关注。

由于算法内容对大部分中学数学老师来说是比较陌生的,在实际教学中又没有现成的经验可以借鉴,因此给我们的教学带来了全方位的挑战。

本研究立足于算法教学实践,重点从算法初步学习内容的特点出发,借鉴布鲁姆的教育目标分类学的理论从教学目标分析入手,在对学生学习基础和学生认知特点进行科学分析的基础上,探讨一种可行性较高的教学模式。

研究过程中,首先在梳理算法知识结构的基础上,运用教育目标分类学理论对算法知识从知识维度和认知维度进行教学目标定位。

然后设计详细教学过程:根据教学目标中涉及的所有知识点,制定要实现的总目标的过程中必须完成的教学子目标,而后依据算法知识特点及课程标准要求达到的程度安排教学方法,从而完成教学活动设计和教学顺序安排。

最后,通过教学实施,对教学效果进行调查研究。

通过本研究得到的主要结论如下:1.目标分类教学策略对算法初步的教与学有显著的促进作用。

2.算法初步的学习过程既要注重算法思想的培养,又要重视技能方面的训练。

3.算法教学要重视案例的选取,重视调动学生学习的兴趣,从简单有趣的案例入手,让学生循序渐进的领悟算法的内涵。

让学生经历认知——模仿——理解——运用——分析——评价的过程是目标教学的指导思想。

算法教学策略(一)充分激发学生学习算法的兴趣爱因斯坦曾经说:兴趣是最好的老师。

瓦特从观察蒸汽冲起水壶盖的兴趣开始发明了蒸汽机,是人类的工业文明步入了崭新的蒸汽机时代,牛顿对树上掉落的苹果产生浓厚的兴趣,发明了万有引力定律,通过对两种算法------辗转相处法和更相减损术,使学生在欣赏中外古代数学优秀成果的过程中,体会两种算法的异曲同工之妙,介以激发学生学习的兴趣算法教学策略(二)既要讲算则又要讲算理在教学中,要注意不要把算则讲成单独的算法语言或程序设计,要体现数学与算法的有机结合,让学生理解数学再利用算法在解决问题中的作用以及算法对学习数学的要求。

算法设计指导教程

算法设计指导教程

算法设计指导教程一、引言算法是计算机科学中非常重要的概念,它是解决问题的一种方法论。

在计算机科学的发展过程中,众多优秀的算法被提出并应用于各个领域。

本文旨在为读者提供一份算法设计的指导教程,帮助读者理解和应用常用的算法。

二、算法设计的基本原则1. 算法的可读性和可理解性:良好的算法应该具备清晰明了的逻辑结构,使得他人能够快速理解和使用。

2. 算法的高效性:算法应该能够在合理的时间内解决问题,尽量避免无效的计算和重复的操作。

3. 算法的正确性:算法在解决问题时应该能够得到正确的结果,不产生错误或歧义。

4. 算法的鲁棒性:算法应该能够处理各种异常情况,具备一定的容错能力。

三、算法设计的基本步骤1. 确定问题:首先,需要明确问题的具体描述和要求,明确问题的输入和输出。

2. 分析问题:根据问题的特点,进行问题分析,找出问题的关键点和难点。

3. 设计算法:根据问题的特点和分析结果,设计合适的算法,可以参考已有的算法或者创造新的算法。

4. 实现算法:将算法转化为具体的计算机程序,可以使用编程语言进行实现。

5. 测试算法:对实现的算法进行测试,验证算法的正确性和效率。

6. 优化算法:根据测试结果,对算法进行优化,提高算法的效率和性能。

7. 文档化算法:根据实现的算法编写详细的文档,包括算法的描述、输入输出的格式和示例等。

四、常用的算法设计方法1. 贪心算法:贪心算法是一种简单而有效的算法设计方法,它在每一步选择中都采取当前状态下的最优选择,从而希望能够达到全局最优解。

2. 分治算法:分治算法将问题划分为多个子问题,分别解决每个子问题,最后将子问题的解合并得到原问题的解。

3. 动态规划算法:动态规划算法是一种将问题划分为多个阶段,并记录每个阶段的最优解的方法,通过递推来得到最终的解。

4. 回溯算法:回溯算法是一种递归的算法设计方法,通过尝试所有可能的解,并在尝试过程中逐步排除不符合要求的解,最终找到符合要求的解。

《基本算法》教案

《基本算法》教案

《基本算法》教案第一章:算法概述1.1 算法的定义介绍算法的概念和重要性解释算法在解决问题中的作用1.2 算法的特性讨论算法的准确性和效率探讨算法的可读性和可维护性1.3 算法的设计方法介绍常见的算法设计方法,如贪心法、分治法、动态规划法等第二章:简单的排序算法2.1 冒泡排序算法介绍冒泡排序的原理和步骤编写冒泡排序的伪代码2.2 选择排序算法介绍选择排序的原理和步骤编写选择排序的伪代码2.3 插入排序算法介绍插入排序的原理和步骤编写插入排序的伪代码第三章:图的基本算法3.1 图的表示方法介绍图的邻接矩阵和邻接列表表示方法3.2 深度优先搜索算法介绍深度优先搜索的原理和步骤编写深度优先搜索的伪代码3.3 广度优先搜索算法介绍广度优先搜索的原理和步骤编写广度优先搜索的伪代码第四章:动态规划算法4.1 动态规划概述介绍动态规划的概念和应用场景解释动态规划的基本原理4.2 动态规划解题步骤讨论动态规划解题的步骤和技巧给出动态规划解题的一般框架4.3 常见的动态规划问题解决一些典型的动态规划问题,如背包问题、最长公共子序列等第五章:算法评估与优化5.1 算法评估概述介绍算法评估的目的和方法讨论评估算法性能的指标,如时间复杂度和空间复杂度5.2 算法优化技巧介绍常见的算法优化技巧,如避免重复计算、使用缓存等5.3 算法效率分析分析算法的时间复杂度和空间复杂度讨论如何选择合适的算法based on given requirements.第六章:分支界限法6.1 分支界限法概述介绍分支界限法的原理和应用解释分支界限法在解决优化问题上的优势6.2 分支界限法的实现步骤讨论分支界限法解决问题的步骤,包括建树、剪枝等编写分支界限法的伪代码6.3 典型的分支界限法问题解决一些典型的分支界限法问题,如0-1背包问题、最长路径问题等第七章:回溯法7.1 回溯法概述介绍回溯法的原理和应用解释回溯法在解决组合优化问题上的优势7.2 回溯法的实现步骤讨论回溯法解决问题的步骤,包括递归、剪枝等编写回溯法的伪代码7.3 典型的回溯法问题解决一些典型的回溯法问题,如八皇后问题、0-1背包问题等第八章:分支界限法与回溯法的比较8.1 分支界限法与回溯法的区别分析分支界限法与回溯法在解决问题时的不同策略讨论两种算法的适用场景和优缺点8.2 分支界限法与回溯法的结合介绍如何将分支界限法与回溯法结合以提高算法性能8.3 实际应用案例分析分析实际应用中分支界限法与回溯法的使用和效果第九章:启发式算法9.1 启发式算法概述介绍启发式算法的原理和应用解释启发式算法在解决NP难问题上的优势9.2 常见的启发式算法讨论常见的启发式算法,如遗传算法、模拟退火算法、蚁群算法等9.3 启发式算法的应用解决一些典型的启发式算法问题,如旅行商问题、作业调度问题等第十章:算法设计与分析总结10.1 算法设计方法总结回顾本课程所学的算法设计方法,如贪心法、分治法、动态规划法等10.2 算法评估与优化总结总结本课程所学的算法评估与优化技巧10.3 算法应用与未来趋势探讨算法在实际应用中的重要性分析算法在未来发展中的趋势和挑战第十一章:算法竞赛与算法模型11.1 算法竞赛简介介绍算法竞赛的背景和意义分析参加算法竞赛的准备工作和要求11.2 常见算法竞赛平台讨论常见的算法竞赛平台,如LeetCode、Codeforces、TopCoder等分析这些平台的特点和题目类型11.3 算法模型的建立介绍如何建立算法模型,包括问题的定义、数据的表示等讨论算法模型在算法竞赛中的应用和重要性第十二章:并行算法12.1 并行算法的基本概念介绍并行算法的基本概念,如并行计算、并发计算等解释并行算法在解决问题中的优势和挑战12.2 并行算法的实现方法讨论并行算法的实现方法,如多线程、多进程、分布式计算等分析不同实现方法的特点和适用场景12.3 典型的并行算法介绍一些典型的并行算法,如矩阵乘法、排序算法等讨论并行算法在实际应用中的性能优化问题第十三章:概率算法13.1 概率算法的概念与特点介绍概率算法的概念和特点,如随机性、不确定性和容错性解释概率算法在解决某些问题上的优势13.2 典型的概率算法讨论典型的概率算法,如蒙特卡洛算法、随机化算法等分析这些算法在实际应用中的效果和限制13.3 概率算法的应用解决一些典型的概率算法应用问题,如估算质数个数、求解最短路径等第十四章:算法伦理与安全性14.1 算法伦理概述介绍算法伦理的概念和重要性讨论算法伦理在数据隐私、歧视和透明度等方面的问题14.2 算法的安全性解释算法安全性的概念和重要性讨论算法安全性在密码学、网络安全等领域的应用14.3 算法伦理与安全性的实践指导给出在设计和实现算法时考虑伦理和安全的实践指导第十五章:算法发展趋势与展望15.1 算法研究的新领域介绍算法研究的新领域,如机器学习算法、量子算法等分析这些新领域的发展潜力和应用前景15.2 算法技术的创新与应用讨论算法技术的创新点,如自动调参、算法优化等分析算法技术在各个领域的应用和发展趋势15.3 算法教育的未来展望探讨算法教育在培养新一代算法人才方面的作用和挑战分析算法教育在未来发展中的趋势和机遇重点和难点解析1. 算法的定义、特性和设计方法:理解算法的概念、特性以及设计方法是学习算法的基础,对于后续算法的理解和应用具有重要意义。

实验项目二:算法的基本策略

实验项目二:算法的基本策略

《算法设计与分析》实验报告实验项目(二)算法的基本策略四、实验内容与步骤1、编写程序,分别用二分法和牛顿迭代法求解方程x3– 3x– 1 = 0在x = 2附近的实根,要求计算精确到小数点后7 位数字为止,并将求出的近似结果与理论值2cos20 比较误差大小。

设二分法的初始迭代区间为[1, 3],牛顿迭代法的起点为4。

2、将一X100 元的钞票换成1 元、2元、5 元和10 元的零钱,每种零钞至少一X,编写程序输出所有的换法,尽可能地提高算法效率。

3、用动态规划求解设备更新问题。

某人打算购买一辆新的小货车用于运货,货车的售价是22 万元人民币。

货车购买后,每年的各种保险费、养护费等费用如下表:如果5年内将货车售出,并再购买新车,5 年内的二手车销售价如下表:设计一种购买货车的方案,使5 年内用车的总费用最少。

选作:将其中所有的数据,包括售价、年份、各年份的费用和各年份二手车销售价等的数据改为任意值。

1.二分法:#include<stdio.h>#include<math.h>void main(){double x,x1=1,x2=3,f1,f2,f;f1=x1*x1*x1-3*x1-1;f2=x2*x2*x2-3*x2-1;if(f1*f2>0)printf("在此区间没有根!");else{do{x=(x1+x2)/2;f=x*x*x-3*x-1;if(f==0)break;else if(f1*f>0){x1=x;f1=f;}else{x2=x;}}while(fabs(x1-x2)>=0.000001);printf("近似值为:%.7f\n",x);printf("与理论值相差为:%.7f",x-1.8793852);}}牛顿迭代法:#include<stdio.h>#include<math.h>void main(){double f0,f1,x0,x1=2;do{x0=x1;f0=3*x0*x0-3;f1=x0*x0*x0-3*x0-1;x1=x0-f1/f0;}while(fabs(x1-x0)>=0.0000001);printf("近似值为:%.7f",x1);printf("与理论值相差: %.7f",x1-1.8793852); }2.#include<iostream>using namespace std;int main(){int N,i,j,k,l,n=0;3.源代码:#include <iostream>#include <vector>using namespace std;int pro[5] = { 3,5,10,16,21 };//货车保护费int sale[6] = { 0,17,15,7,4,2 };//二手车销售价格int minmoney = -65536;#define MAX 20int num[MAX] = { 1,2,3,4 };int n = 0;vector<vector<int>>ps;void solve(int n) {vector<vector<int>>ps1;vector<vector<int>>::iterator it;vector<int>s;ps.push_back(s);for (int i = 0; i < n; i++) {}}int main() {for (int i = 1; i<5; i++) {pro[i] += pro[i - 1];}vector<int>mi;solve(4);show();system("pause");return 0;}程序运行结果:。

【算法复习一】常见的算法策略汇总

【算法复习一】常见的算法策略汇总

【算法复习一】常见的算法策略汇总一,概述算法策略和算法是有区别的,它们是算法设计中的两个方面,算法策略是面向问题的,算法是面向实现的;但二者又是不可分的,首先是通过算法策略才找出解决问题的算法,其次对于用不同算法求解的问题算法策略是自然不同的。

二,算法策略1)递推策略:“递推法”和贪心算法一样也是由当前问题的逐步解决从而得到整个问题的解,只是依赖的是信息间本身的递推关系,每一步不需要策略参与到算法中,它们更多地用于计算。

2)递归策略:递归法是利用大问题与其子问题间的递归关系来解决问题的。

每次找出大问题与小的子问题之间的关系,直到小的子问题很容易解决,再由小的子问题的解导出大问题的解。

例如:汉诺塔问题3)穷举策略:对所有可能的解逐一尝试。

4)递归回溯策略:类似于穷举法的思想,递归回朔法通过递归尝试遍问题各个可能解的通路,发现此路不通时回朔到上一步继续尝试别的通路。

5)分治策略:求解的则是较复杂的问题,这类问题是可以被分解成独立的子问题来解决的,将两个或两个以上的独立子问题的解“合成”,就得到较大的子问题的解,最后合成为总问题的解。

(注意一定是可以分解成独立子问题,否则会重复计算公共子问题)6)动态规划策略:动态规划法与贪心法类似,要求问题具有最优子结构(即最优解包含子问题的最优解),是一种自底向上的求解思路,与递归正好相反,每次求解到一个阶段时,该阶段求解所依赖的子问题已经完全求解完毕,因此每一步的求解都是在直到全部所需信息的情况下进行的,因此可以得到全局最优解。

7)贪心策略:如果想要得到最优解,需要对问题性质有更严格的要求,除了要有最优子结构外,还要求问题具有贪婪选择性质。

具体来说就是:贪心是一种策略,即每一步都要选择当前看来最好的,做完此选择后便将问题化为一个(仅仅一个)子问题,这是一个顺序的求解过程,每一步都是单独考虑,只考虑局部最优,因为并没有完成对之后子问题的求解,所以贪心算法不能完成对整个解空间的搜索,因此通常不能得到最优解。

第四章1算法策略迭代算法

第四章1算法策略迭代算法

第四章1算法策略迭代算法迭代算法是一种通过重复应用一些过程或步骤来逐步逼近解的策略。

在计算机科学中,迭代算法是解决问题的一种常见方法,尤其在计算复杂度比较高的情况下,迭代算法可以提供一种有效的解决方案。

迭代算法的核心思想是将问题分解成一系列小的子问题,并通过重复执行一些步骤来逐渐逼近解。

每次迭代时,算法会根据上一次迭代的结果来更新当前的状态,然后继续下一次迭代。

这样的迭代过程会持续进行,直到达到一些停止条件为止。

迭代算法可以应用在各个领域的问题中,比如数值计算、优化问题、问题等。

下面将介绍一些常见的迭代算法。

1.迭代加深:这是一种在问题中应用的常见迭代算法。

它通过逐渐增加的深度来逼近解。

首先进行深度为1的,如果没有找到解,则增加深度,再次进行。

通过不断增加深度,直到找到解为止。

2.迭代法解线性方程组:线性方程组的解可以通过迭代算法逐步求得。

一种常见的迭代算法是雅可比迭代法,它通过不断迭代解方程组的近似解,直到满足特定的收敛准则为止。

3.迭代法求函数零点:对于给定的函数,通过迭代算法可以逐步逼近函数的零点。

其中,牛顿迭代法是一种常见的迭代算法,它通过使用函数的导数和当前函数值来逐步逼近零点。

除了上述几种常见的迭代算法,还有其他很多迭代算法方法,如迭代法解非线性方程组、最小二乘法、迭代法求特征值等。

迭代算法的优点是它可以解决很多复杂的问题,并且可以提供一种近似解。

此外,迭代算法通常比较灵活,可以根据实际情况进行调整。

迭代算法的缺点是它可能需要进行大量的迭代次数才能得到满意的结果,并且在一些情况下可能无法收敛到解。

总之,迭代算法是一种常见的算法策略,可以应用于很多领域的问题。

通过不断迭代,算法可以逐步逼近最优解或者满足特定的目标。

虽然迭代算法可能需要较长时间才能得到完美的解,但它是解决复杂问题的一种有效方法。

基础算法策略-枚举.

基础算法策略-枚举.

注意: 1. 加号与等号各自需要两根火柴棍 2. 如果A≠B,则A+B=C与B+A=C视为不同的等式(A、B、 C>=0) 3. n根火柴棍必须全部用上
分析
1.
2.
3. 4.
5.
0~9的数字所用的火柴数:6,2,5,5,4,5,6,3,7,6 对于N<=24,去掉+,=,实际上数字只有20根火柴。 首先考虑解集合,因为最多为20根火柴组成数字: 不可能为10个1; 不可能8个1,1个4; 不可能为7个1,2个7或1个0; ….. C不会超过1000
【输入样例】 3 1 5 {共有3个嫌疑人,其中有1个人始终说假话,有5条证词} MIKE CHARLES 嫌疑人的名字(3个)
KATE
MIKE:I am guilty. MIKE:Today is Sunday. CHARLES:MIKE is guilty. KATE:I am guilty. KATE:How are you?? 【输出样例】
证词~(5条)
MIKE
分析

这道题的关键点是“如何能够快速正确实现出来” ,事 实上这道题对编码能力的要求要大于对算法本身的要求。 由于这道题的数据范围并不是很大,但需要进行“字符串 处理”这种比较麻烦的工作,因此在比赛时就可以采用效 率低一些的枚举算法来换取编码上的简单。
局部枚举
例题4:新年好

某城里有n个车站,m条双向公路连接其中的某 些车站。每两个车站最多用一条公路直接相连, 从任何一个车站出发都可以经过一条或多条公 路到达其他车站,但不同的路径需要花费的时 间可能不同。在一条路上花费的时间等于路径 上所有公路需要的时间之和。

佳佳的家在车站1,他有五个亲戚,分别住在 车站a,b,c,d,e。过年了,他需要从自己的家出 发,拜访每个亲戚(顺序任意),给他们送去 节日的祝福。怎样走,才需要最少的时间?
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

①号
②号 四种三格板
③号
④号
这样的棋盘我们称作“三格板”,残缺棋盘问题就是要用这 四种三格板覆盖更大的残缺棋盘。在此覆盖中要求: 1)两个三格板不能重叠 2)三格板不能覆盖残缺方格,但必须覆盖其他所有的方格 在这种限制条件下,所需要的三格板总数为(2k×2k -1 )/3。
算法设计1:下面用分而治之方法解决残缺棋盘问题。 1)问题分解过程如下: 以k=2时的问题为例,用二分法进行分解,得到的是如下图48,用双线划分的四个k=1的棋盘。但要注意这四个棋盘,并 不都是与原问题相似且独立的子问题。因为当如图4-8中的 残缺方格在左上部时,第1个子问题与原问题相似,而右上 角、左下角和右下角三个子棋盘(也就是图中标识为2、3、 4号子棋盘),并不是原问题的相似子问题,自然也就不能 独立求解了。当使用一个①号三格板(图中阴影)覆盖2、3、 4号三个子棋盘的各一个方格后,如4-8右图所示,我们把覆 盖后的方格,也看作是残缺方格(称为“伪”残缺方格), 这时的2、3、4号子问题就是独立且与原问题相似的子问题 了。
一个4*4的残缺棋盘
从以上例子还可以发现,当残缺方格在第1个子棋盘,用①号三 格板覆盖其余三个子棋盘的交界方格,可以使另外三个子棋 盘转化为独立子问题;同样地(如下图4-9所示),当残缺方 格在第2个子棋盘时,则首先用②号三格板进行棋盘覆盖,当 残缺方格在第3个子棋盘时,则首先用③号三格板进行棋盘覆 盖,当残缺方格在第4个子棋盘时,则首先用④号三格板进行 棋盘覆盖,这样就使另外三个子棋盘转化为独立子问题。
多数问题需要所有子问题的解,并由子问题的解,使用恰 当的方法合并成为整个问题的解,比如合并排序,就是不断将 子问题中已排好序的解合并成较大规模的有序子集。
• 适合用分治法策略的问题 当求解一个输入规模为n且取值又相当大的问题时,用蛮 力策略效率一般得不到保证。若问题能满足以下几个条件, 就能用分治法来提高解决问题的效率。 1)能将这n个数据分解成k个不同子集合,且得到k个子集 合是可以独立求解的子问题,其中1<k≤n; 2)分解所得到的子问题与原问题具有相似的结构,便于 利用递归或循环机制;
一个4*4的残缺棋盘及其解
算法如下: int amount=0; main( ) { int size=1,x,y; input(k); for (i=1;i<=k;i++) size=size*2; print(“input incomplete pane ”); input(x,y); Cover(0, 0, x, y, size); }
Cover(int tr, int tc, int dr, int dc, int size) { if (size<2) return; int t = amount ++, // 所使用的三格板的数目 s=size/2; // 子问题棋盘大小 if (dr < tr + s && dc < tc + s) / /残缺方格位于左上棋盘 {Cover ( tr, tc, dr, dc, s); Board[tr + s - 1][tc + s] = t; // 覆盖1号三格板 Board[tr + s][tc + s - 1] = t; Board[tr + s][tc + s] = t; Cover (tr, tc+s, tr+s-1, tc+s, s); // 覆盖其余部分 Cover(tr+s, tc, tr+s, tc+s-1, s); Cover(tr+s, tc+s, tr+s, tc+s, s); }
四、合并分类(归并排序)
先看插入排序: Void inபைடு நூலகம்ertsort(int a[ ],n) { //将数组a中的n个元素按非降序排列 a[0]=-32768;
for (j=2;j<=n;j++)
{item=a[j]; i=j-1; while(item<a[i]) {a[i+1]=a[i];i=i-1;} a[i+1] =item;
如下图4-9:
图4-9
其它4*4的残缺棋盘
同样地k=1,2,3,4……都是如此,k=1为停止条件。
2)棋盘的识别 棋盘的规模是一个必要的信息,有了这个信息,只要知道其左上 角的左上角方格所在行、列就可以唯一确定一个棋盘了,残 缺方格或“伪”残缺方格直接用行、列号记录。 • tr 棋盘中左上角方格所在行。 • tc 棋盘中左上角方格所在列。 • dr 残缺方块所在行。 • dl 残缺方块所在列。 • size 棋盘的行数或列数。 数据结构设计:用二维数组board[ ][ ],模拟棋盘。覆盖 残缺棋盘所需要的三格板数目为:( size2 -1 ) / 3 将这些三格板编号为1到( s i z e2-1 ) / 3。则将残缺棋 盘三格板编号的存储在数组board[ ][ ]的对应位置中,这 样输出数组内容就是问题的解。结合图4-9,理解算法。
else if (dr >= tr + s && dc >= tc + s)

// 残缺方格位于右下象
{Cover(tr+s, tc+s, dr, dc, s); Board[tr + s - 1][tc + s - 1] = t; // 覆盖4号三格板 Board[tr + s - 1][tc + s] = t; Board[tr + s][tc + s - 1] = t; Cover (tr, tc, tr+s-1, tc+s-1, s); //覆盖其余部分 Cover (tr, tc+s, tr+s-1, tc+s, s); Cover(tr+s, tc, tr+s, tc+s-1, s); } } 算法分析:因为要覆盖 void OutputBoard(int size) (size2 -1)/ 3个三格板, { for (int i = 0; i < size; i++) 所以算法的时间复杂性 为O(size2)。 { for (int j = 0; j < size; j++) print( Board[i][j]); print(“换行符”); } }
最好情况(递增):n-1
最坏情况(递减):2(n-1) 平均情况:3(n-1)/2
算法3:递归求取最大和最小元素
float a[n]; maxmin(int i, int j ,float &fmax, float &fmin) { int mid; float lmax, lmin, rmax, rmin; if(i=j) {fmax= a[i]; fmin=a[i];} else if (i=j-1) if(a[i]<a[j]) { fmax=a[j];fmin=a[i];} else {fmax=a[i]; fmin=a[j];} 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; } }
max=a[i]; min=a[i];
}
}
平均比较次数:2*(n-1)
算法2: maxmin( float a[],int n) { max==min=a[1]; for(i=2 i<=n i++ ) if(max<a[i]) max=a[i]; else if(min>a[i]) } min=a[i];
•设计模式:
Divide-and-Conquer(int n)
{ if(n≤n0) { 解子问题;
//n为问题规模
//n0 为可解子问题的规模
return(子问题的解); } for(i=1 ;i<=k;i++) //分解为较小子问题p1,p2,……pk yi=Divide-and-Conquer(|Pi|); //递归解决Pi T=MERGE(y1,y2,...,yk); return(T); //合并子问题
1)分解:将原问题分解为若干个规模较小,相互独立,与原问 题形式相同的子问题; 2)解决:若子问题规模较小而容易被解决则直接解,否则再继 续分解为更小的子问题,直到容易解决; 3)合并:将已求解的各个子问题的解,逐步合并为原问题的解。
有时问题分解后,不必求解所有的子问题,也就不必作第三步 的操作。比如折半查找,在判别出问题的解在某一个子问题中 后,其它的子问题就不必求解了,问题的解就是最后(最小) 的子问题的解。分治法的这类应用,又称为“减治法”。
}
}
再看归并排序
基本思想:将集合a分成两个集子合,递归地对每个子 集合单独分类,然后将已排序的两个子集合归并成一 个集合
void mergesort(int a[N],int low,int high) { int b[N]; if(low<high) m=(low+high)/2;
mergesort(a,low,m);
算法分析: 递归关系式(比较次数):
当n是2的幂时,即对于这个某个正整数k,n=2k,有
可以证明,任何以元素 比较为基础的找最大和 最小元素的算法,其元 素比较下界均为 次。 因此,过程MAXMIN在这 种意义上是最优的。
三、二分法不相似情况
【例】残缺棋盘 残缺棋盘是一个有2k×2k (k≥1)个方格的棋盘,其中恰有 一个方格残缺。图4-7给出k=1时各种可能的残缺棋盘,其 中残缺的方格用阴影表示。
相关文档
最新文档