算法设计实例教程 第2章 基础算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2 基础算法
算法设计实 例教程
2 基础算法
教 学 分 析
CONCENTS
目1 录2
3 4 5 6 7 8 9
第1章 数据结构基础
第2章 基础算法
第3章 排序算法 第4章 查 找 第5章 字符串和高精度运算 第6章 图论算法 第7章 动态规划算法 第8章计算几何基础 第9章 高级算法
2 基础算法
第2章 基础算法
图2-1 2名运动员的对阵矩阵
图2-2 4名运动员的对阵矩阵
2 基础算法
2.1.2 分治法应用举例1:循环赛日程表
通过观察由4名运动员组成的比赛日程安排表,我们可以发现它可以分解为2个两人组比 赛日常表的组合,将矩阵右上角2×2子矩阵的值直接复制到左下角,同样,矩阵左上角 的2×2子矩阵也被复制到了右下角。
发现规律了吗?右上子矩阵的值=左上的子矩阵+2。而这个2正是右上子矩阵相对于左上 子矩阵在坐标上的偏移量。由此,我们可以按照这样的规律分别填写每一个2×2子矩阵 的值。
2 基础算法
2.1.2 分治法应用举例1:循环赛日程表
我们可以将该规律推广到n=2k的情况。按照分治的策略,将所有运 动员平均分为两组,n个运动员的比赛日程表就可以通过两个n/2个 运动员的比赛日程表来决定。如果分解后的小组成员的数量依然大于 2,则可以使用分治法继续对运动员进行分割,直到每一组都只包含 两个运动员,就可以直接得到一个2×2的比赛日程表。
2.1 分治法 2.1.1 分治法的基本概念
分治法,从字面意思理解就是分而治之,其本质就是将一个原本规模较 大的问题分解为若干规模较小且更容易求解的子问题,分别求解每个子 问题,对求解出的结果进行合并得到原问题的最终解答。
2 基础算法
第2章 基础算法
2.1 分治法
2.1.1 分治法的基本概念 使用分治法设计算法,通常包括以下三个步骤:
8 输出样例
12345678 21436587 34127856 43218765 56781234 65872143 78563412 87654321
2 基础算法
2.1.2 分治法应用举例1: 2名运动员)开始,分析循环赛日程表问 题的结构特征。
问题描述
设有n=2k个运动员要进行网球循 环赛。现要设计一个满足以下要 求的比赛日程表:
(1)每个选手必须与其他n-1个选手 各赛一次;
(2)每个选手一天只能赛一次;
(3)循环赛一共进行n-1天。
输入说明
一个正整数n,表示参加比赛的运 动员的数量,其中n=2K(k>0)。
输出说明
输入样例 输出样例
输出说明 一个n×n的二维矩阵,其中第0列依次是每一 位运动员的编号(运动员的编号从1开始), 剩下的n-1列是循环赛的编排表,其中第i行第 j(j>0)列的数值表示编号为i+1的运动员在 第j天遇到的运动员的编号。 输入样例
当n=4时,将有4位运动员参与循环赛。这4位运动员可以两两分为一组,比 如1号与2号为一组,3号与4号为一组,每一组可以在同一天各自进行循环 赛。比如在比赛的第1天,在第一组是1号与2号,第二组是3号与4号比赛, 因此数组的第1列的值分别为[2,1,4,3]。第二天和第三天两组交叉运动员, 数组的第2列的值分别为[2,1,4,3]第二天第一组的1号运动员分别对阵3号和4 号,第二组的3号运动员分别对阵1号和2号。 得到的日程安排表如下所示:
(1)分解:将要求解的问题划分成若干规模较小的同类子问题,且每个子问 题是相互独立的;
(2)求解:当子问题的规模足够小,能够使用较简单的方法解决时,对子问 题进行求解;
(3)合并:合并子问题的解,构成最终的答案
2 基础算法
2.1.2 分治法应用举例1:循环赛日程表
时间限制:1000ms 内存限制: 32MB
当只有两位运动员时(即n=2),分别是: 运动员1号和运动员2号,显然他们之间 只需要安排一场比赛就可以了,而这场比 赛也只需要安排在第一天就可以结束,因 此比赛日程安排可以用如下的一个2×2 的二维矩阵A表示:
图中所示,矩阵第0列的两个元素A[0][0]和A[1][0]分别表示运动员的编号1号 和2号,而第1列的元素值则表示第1天所有的对阵安排。其中,A[0][1]的值 为2,表示1号选手在第1天遇到的是2号运动员,A[1][1]的值为1,表示2号 选手在第1天遇到的是1号运动员。从这个分析,我们也可以得出一个显然 的结论,即这个日常安排表是一个对称矩阵。
输入样例 12345678900 98765432100 输出样例 1219326311126352690000
算法分析
由于编程语言提供的基本数值数据类型表示的数值范围有限,当两 个大数进行相乘运算时,很可能会超过计算机数值的表示范围,从 而导致计算溢出错误。比如,一个long int类型数值由4个字节组成, 其可以表示范围是(-231~231-1,即-2147483648~2147483647)。 当两个long int整型相乘,其结果最大会到达2的62次方,远远超过 了long int类型能够表示的范围。 因此,用直接的相乘运算不能满足较大规模的高精度数值计算,需 要利用其他方法间接完成计算,于是产生了大数运算。
由于这个4×4的矩阵具有的对称性,我们只需要关注位于左上和右上的两个2×2子矩阵 的值的特点。左上的2×2子矩阵元素包括A[0][0]、A[0][1]、A[1][0]、A[1][1],它代表 的是1号运动员与2号运动员的赛程安排,填入的值分别为1、2、2、1。右上的2×2子矩 阵元素包括A[0][2]、A[0][3]、A[1][2]、A[1][3]它代表的是3号运动员与4号运动员的赛 程安排,填入的值分别为3、4、4、3。但是我们可以换个视角再来看这组值的特点,即 A[0][0+2]、A[0+0][1+2]、A[1+0][0+2]、A[1+0][1+2],它们的值分别是1+2、2+2、 2+2、1+2。
这是一个典型的可以用分治法来解决的问题。将一个原本规模为n的 问题逐层分解,而且每个子问题的结构都与原问题形式相同且相互独 立,直到子问题的解可以轻而易举地获得,就可以通过递归地解决这 些子问题,然后合并各个子问题地解得到原问题的解。
2 基础算法
2.1.3 分治法应用 举例2:大整数乘法
时间限制:1000ms 内存限制:65536KB 问题描述 求两个不超过200位的非负整数的积。 输入说明 有两行,每行是一个不超过200位的非负整数,没有多余的 前导0。 输出说明 一行,即相乘后的结果。结果里不能有多余的前导0,即如 果结果是342,那么就不能输出为0342。
相关文档
最新文档