8.3 递归与分治

8.3 递归与分治

这一章节主要介绍递归除了排序与检索以外,更为广泛的应用(实际上是介绍了递归与分治的使用情况与使用意义)。


棋盘覆盖问题

有一个2k*2k的方格棋盘,恰好有一个方格为黑色的,其他都为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。以下是L型牌的四种旋转方式:

在这里插入图片描述
分析:本题的棋盘是2k*2k的,如果使用分治法很容易想到将棋盘切割成4块。此时的四个2k-1*2k-1的方块中必有一个含有一个黑色方块,这个方块可以视作k-1的情况,其他的三个方块全都没有黑格子。我们可以通过下面的方式“构造”出一个黑格子:

在这里插入图片描述

图中的红格子为2k*2k的方格中原有的黑格子,我们取一个L型牌放置在2k*2k的方格中心,保证每一个2k-1*2k-1的区域中都有一个异色的方块。此时我们可以将k的问题分割k-1的四个子问题,假设棋盘为2k*2k的方格时,所放牌的个数为f(k),于是有f(k)=4*f(k-1)+1(1为放置在中间的一个L型牌),f(1)=1。

代码就不写了,因为知道了原理以后这个题就非常简单了。


循环日程表问题

n=2k个运动员进行网球循环赛,需要设计比赛日程表。每个选手必须与其他n-1个选手各赛一次。每个选手每天只能赛一次,循环赛一共进行了n-1天。需要按此要求设计一张比赛日程表,该表第i行第j列表示第i个选手第j天遇到的选手。

1 2 3 4 5 6 7 8
2 1 4 3 6 5 8 7
3 4 1 2 7 8 6 5
4 3 2 1 8 7 6 5
5 6 7 8 1 2 3 4
6 5 8 7 2 1 4 3
7 8 6 5 3 4 1 2
8 7 6 5 4 3 2 1

分析:网上实在是找不到画的好看的图嗷hhhhh。实际上这个问题和递归分治的关系并不大,属于一道找规律的数字方证题,我们仔细观察就可以发现将一个方证切割成四个部分,每个部分都是按照对角线对称,也就是说我们只需要定义第一行(从1-n),然后不停的找下面的规律就可以了。

代码就不写了,主要写了也是找规律,用不到分治的思想(它并没有分治中最重要的一步合并问题)。


巨人与鬼

一组n个巨人正与n个鬼进行战斗,每个巨人的武器是一个质子炮, 它可以把一串质子流射中鬼而把鬼消灭。质子流沿直线行进,在击中鬼时就终止。巨人决定采取下述策略。他们寻找鬼配对,以形成n个巨人─鬼对,。然后每个巨人同时向他选取的鬼射出一串质子流。我们知道,让质子流互相交叉是很危险的。因此巨人选择的配对方式应该使质子流都不会交叉。假定每个巨人和每个鬼的位置都是平面上的一个固定点,并且没有三个位置共线, 求一种配对方案。

分析:就是给你2*n个点,寻找一种两两配对的方式保证两两配对的点的连线不互相交叉。考虑到需要用分治法去解决这个问题,我们需要一种切割的方式将这个问题切割成多个子问题,下面提供一中分割的方式:

在这里插入图片描述
考虑所有点中处于最左下角的那个点,不妨设这个点为一个“鬼”(由于巨人和鬼是一一配对的关系,所以说设为巨人和鬼没有实际的区别)。此时其余的2n-1个点中,n-1个点为“鬼”,n个为巨人。我们只需要找到一个代表“巨人”的点进行连线,保证被这条连线所代表的直线分割出来的两部分中各含有的“鬼”和“巨人”的点的个数相等即可。

按照顺时针的顺序将其他点进行编号,如果第一个点为“巨人”,那配对完成。剩下的“巨人”和“鬼”一样多,而且并不会和这条线段交叉。如果这个点为“鬼”,也就是说当左下角的点与第二个点连线时,上半边的区域中“鬼”的个数比“巨人”多一个(“鬼”只有一个),然而由于最后一个点也需要为“鬼”(不然直接和最后一个点连线即可),当我们与倒数第二个点连线时,上半边的区域中,“鬼”的个数比“巨人”少(因为左下角的点和最后一个点全为“鬼”),但是我们每次检查完一个点,切割完整个图,再检查下一个点切割图时,上半边点的个数+1,也就是说“巨人”和“鬼”点的个数差变化了1。与第二个点连线时,“鬼”比“巨人”多,与倒数第二个点连线时,“巨人”比“鬼”多,那么在中间一定存在某个点,保证上半边和下半边“鬼”和“巨人”个数相等。

根据上面的分析,我们可以确定这种切割方式是一定存在的。由于不知道数据是什么形式提供的,这道题也只介绍思路不进行编写了。


这一章主要是对分治思想的介绍和探究,大家在练习时还是需要找一些难度适中的题目进行实际编写和训练。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
书名:算法设计与分析 作者:王晓东 图书目录 第1章 算法引论 1.1 算法与程序 1.2 表达算法的抽象机制 1.3 描述算法 1.4 算法复杂性分析 小结 习题 第2章 归与分治策略 2.1 速归的概念 2.2 分治法的基本思想 2.3 二分搜索技术 2.4 大整数的乘法 2.5 Strassen矩阵乘法 2.6 棋盘覆盖 2.7 合并排序 2.8 快速排序 2.9 线性时间选择 2.10 最接近点对问题 2.11 循环赛日程表 小结 习题 第3章 动态规划 3.1 矩阵连乘问题 3.2 动态规划算法的基本要素 3.3 最长公共子序列 3.4 凸多边形最优三角剖分 3.5 多边形游戏 3.6 图像压缩 3.7 电路布线 3.8 流水作业调度 3.9 0-1背包问题 3.10 最优二叉搜索树 小结 习题 第4章 贪心算法 4.1 活动安排问题 4.2 贪心算法的基本要素 4.2.1 贪心选择性质 4.2.2 最优子结构性质 4.2.3 贪心算法与动态规划算法的差异 4.3 最优装载 4.4 哈夫曼编码 4.4.1 前缀码 4.4.2 构造哈夫曼编码 4.4.3 哈夫曼算法的正确性 4.5 单源最短路径 4.5.1 算法基本思想 4.5.2 算法的正确性和计算复杂性 4.6 最小生成树 4.6.1 最小生成树性质 4 6.2 Prim算法 4.6.3 Kruskal算法 4.7 多机调度问题 4.8 贪心算法的理论基础 4.8.1 拟阵 4.8.2 带权拟阵的贪心算法 4.8.3 任务时间表问题 小结 习题 第5章 回溯法 5.1 回溯法的算法框架 5.1.1 问题的解空间 5.1.2 回溯法的基本思想 5.1.3 归回溯 5.1.4 迭代回溯 5.1.5 子集树与排列树 5.2 装载问题 5.3 批处理作业调度 5.4 符号三角形问题 5.5 n后问题 5.6 0-1背包问题 5.7 最大团问题 5.8 图的m着色问题 5.9 旅行售货员问题 5.10 圆排列问题 5.11 电路板排列问题 5.12 连续邮资问题 5.13 回溯法的效率分析 小结 习题 第6章 分支限界法 6.1 分支限界法的基本思想 6.2 单源最短路径问题 6.3 装载问题 6.4 布线问题 6.5 0-1背包问题 6.6 最大团问题 6.7 旅行售货员问题 6.8 电路板排列问题 6.9 批处理作业调度 小结 习题 第7章 概率算法 7.1 随机数 .2 数值概率算法 7.2.1 用随机投点法计算л值 7.2.2 计算定积分 7.2.3 解非线性方程组 7.3 舍伍德算法 7.3.1 线性时间选择算法 7.3.2 跳跃表 7.4 拉斯维加斯算法 7.4.1 n后问题 7.4.2 整数因子分解 7.5 蒙特卡罗算法 7.5.1 蒙特卡罗算法的基本思想 7.5.2 主元素问题 7.5.3 素数测试 小结 习题 第8章 NP完全性理论 8.1 计算模型 8.1.1 随机存取机RAM 8.1.2 随机存取存储程序机RASP 8.1.3 RAM模型的变形与简化 8.1.4 图灵机 8.1.5 图灵机模型与RAM模型的关系 8.1.6 问题变换与计算复杂性归约 8.2 P类与NP类问题 8.2.1 非确定性图灵机 8.2.2 P类与NP类语言 8.2.3 多项式时间验证 8.3 NP完全问题 8.3.1 多项式时间变换 8.3.2 Cook定理 8.4 一些典型的NP完全问题 8.4.1 合取范式的可满足性问题 8.4.2 3元合取范式的可满足性问题 8.4.3 团问题 8.4.4 顶点覆盖问题 8.4.5 子集和问题 8.4.6 哈密顿回路问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值