关于这一章节《算法实战策略》有一段概述问题,我认为对于编程人员来说非常有价值,故在这里进行如下的摘抄:

构想算法是很艰难的工作。相比大家都经历过,面对复杂的要求只是傻乎乎地盯着显示器,或者不经过深思熟虑就开始打键盘,结果还要辛辛苦苦修改变得一塌糊涂的代码。经过这些磨难,各位就能切身体会到设计算法的重要性。

与通常所想不同,支配设计算法的并不是一时的灵感,而是许多策略性的选择。构想算法不仅需要理解问题的特性,还要理解执行时间和占用内存空间之间的对立关系,而且要会选择适当的数据结构。

算法设计范式指的是,算法为解决给定问题而采用的策略或观点。有些算法会共享出解决问题时最重要的领会,将之积累起来就会领悟到一种模式。从这个意义上说,这些领会是通过相同策略或相同范式解决问题的。

算法设计范式可作为设计算法的框架,因此,学习这些范式将有助于提高算法设计的能力。

——摘自《算法实战策略》

关于穷举法,可以说是计算机领域最为人熟知但却有大大忽略的一种基础算法了。很多人都会知道,它的思想就是将解空间给一一列举出来然后进行计数或者其他的什么操作。有较好算法基础的人会知道,搜索(DFS、BFS)本质上也是一种穷举,只不过他们针对不同类型的问题所设计出来的基于递归和搜索树结构的穷举方法,这里其实已经开始体现出穷举法解决问题的灵活性,并非很多人印象中那么简单。而利用穷举策略解决问题的时候,还将会面临下面几个大问题:

(1)    穷举过程中重复情况的计算:即我们要设计的穷举过程一定要“有序”,所谓“有序”就是要做到“不重不漏”的一一列举出所有情况。

(2)    穷举过程复杂度的分析:在具体的解题中我们往往会遇到穷举时时间、空间溢出的情况,这时候我们需要做的就是优化,映射到上文提及到的搜索其实就是剪枝策略。

那么下面我们结合这两个方面,通过具体的问题来实战体会这种范式设计思维。

Q:给出学生数n(n≤10)和他们之间的朋友关系,现在进行两两配对,请问有多少种不同的配对方法?

分析:

首先我们思考这道问题会有哪些重复计数的坑,能够看到,我们进行一组配对,比如(1,2)所形成的二元对视无序的,即(1,2)和(2,1)是一样的,对此我们在编程设计中,进行“配对”的时候就不能够设计两层循环了,而是通过规定二元对(a,b)中b>a来排除这些重复情况。

其次是对穷举过程复杂度的分析,基于个问题数据n的最大值,我们能够看到至多穷举的情况数是9*7*5*3*1 = 945,计算机处理起来是绰绰有余的因此不需要考虑优化。

另外要说的一个层面的问题是,在设计穷举的时候,如果说一种情况要分成多个决策过程,那么此时最好的方法就是基于递归和搜索树的深搜策略,它更加强调各种情况生成时的联系,而如果各种情况相对独立的话,那么进行简单的暴力枚举即可。

这道题目的函数代码如下:

 int n;

bool areFriend[][];

int countPairings(bool taken[])//标记配对情况的数组

{

    int  firstFree = -;

    for(int i = ;i < n;i++)//找到当前bool表中第一个没有配对的人

    {

          if(!taken[i])

          {

               firstFree = i;

               break;

          }

    }

    if(firstFree == -)  return ;   //所有人已完成配对,得到一种配对方法,返回1

    int ret = ;

    for(int pairWith = first +;pairWith < n;++pairWith)

    {

         if(!taken[pairWith] && areFriend[firstFree][pairWith])

         {

            taken[firstFree] = true;

            taken[pairWith]  = true;

            ret += countPairings(taken);

            taken[firstFree] = false;

            taken[pairWith]  = false;   

         }

    }

    return ret;

}

//由于数据较小,为了处理的方便,对于n<10的情况,我们可以将缺少的人记为已经配对,而在areFriend[][]需要初始化为0;而这一步骤在上面的部分代码中并没有体现,

//读者在完成完成代码的时候需要注意补充。

《算法问题实战策略》-chaper7-穷举法的更多相关文章

  1. 基本算法思想之穷举法(C++语言描述)

    穷举算法(Exhaustive Attack method)是最简单的一种算法,其依赖于计算机的强大计算能力来穷尽每一种可能性,从而达到求解问题的目的.穷举算法效率不高,但是适应于一些没有规律可循的场 ...

  2. 通过穷举法快速破解excel或word加密文档最高15位密码

    1.打开文件 2.工具 --- 宏 ---- 录制新宏 --- 输入名字如 :aa 3.停止录制 ( 这样得到一个空宏 ) 4.工具 --- 宏 ---- 宏 , 选 aa, 点编辑按钮 5.删除窗口 ...

  3. for循环语句以及迭代法和穷举法

    循环语句: 四要素:初始条件,循环条件,状态改变,循环体 for(初始条件;循环条件;状态改变){ //循环体} 案例1:打印等腰直角三角形和菱形 左上三角 static void Main(stri ...

  4. C#4 for循环 迭代法 穷举法应用

    for()循环. 四要素: 初始条件,循环条件,状态改变,循环体. 执行过程: 初始条件--循环条件--循环体--状态改变--循环条件.... 注意:for的小括号里面分号隔开,for的小括号后不要加 ...

  5. C# for 循环 迭代法 穷举法

    for()循环. 四要素: 初始条件,循环条件,状态改变,循环体. 执行过程: 初始条件--循环条件--循环体--状态改变--循环条件.... 注意:for的小括号里面分号隔开,for的小括号后不要加 ...

  6. 【2-24】for循环嵌套,跳转语句,异常语句,穷举法、迭代法

    For循环嵌套与if嵌套相似,是在for中再套for,其结构如下: For(;;) { For(;;){} }经典题型为打印星星例: Console.Write("请输入一个奇数:" ...

  7. 穷举法、for循环、函数、作用域、斐波那契数

    1.穷举法 枚举所有可能性,直到得到正确的答案或者尝试完所有值. 穷举法经常是解决问题的最实用的方法,它实现起来热别容易,并且易于理解. 2.for循环 for语句一般形式如下: for variab ...

  8. C# 异常语句 跳转语句 while循环 穷举法 迭代法

    一  异常语句   ♦ try.....catch....finally 结构形式 try{ 可能会出错的代码语句 如果这里出错了,那么不会在继续下面的代码,而是直接进入catch中处理异常}catc ...

  9. python 穷举法 算24点(史上最简短代码)

    本来想用回溯法实现 算24点.题目都拟好了,就是<python 回溯法 子集树模板 系列 -- 7.24点>.无奈想了一天,没有头绪.只好改用暴力穷举法. 思路说明 根据四个数,三个运算符 ...

随机推荐

  1. xeam Build Definition Extension uninstall 卸载

    之前在VS上装了Build definition 的扩展,后来发现很不好用,想卸载掉,就增 工具下面找add-in manager, 结果找不到,external tools下面也找不到, googl ...

  2. gridview添加header

    gridview是不能添加header的,这里的解决方法是将listview改造成gridview使用,功能很好用,唯一的缺点是列数不能自适应 示例代码下载地址http://pan.baidu.com ...

  3. apk代码的破解

    方法一:dexdump方法(效果很不好,推荐指数*) 1.搜索到dexdump.exe所在目录: 2.将apk包中的**.dex文件存放到上面目录: 3.命令行中进入上面目录,执行:dexdump   ...

  4. 【Python之旅】第六篇(七):开发简易主机批量管理工具

    [Python之旅]第六篇(七):开发简易主机批量管理工具 python 软件开发 Paramiko模块 批量主机管理 摘要: 通过前面对Paramiko模块的学习与使用,以及Python中多线程与多 ...

  5. Oracle数据表恢复

    用于直接drop掉表的情况(plsql developer直接删掉表就是drop操作) 查删除的表select object_name,original_name,partition_name,typ ...

  6. (转)PHP中构造函数和析构函数解析

    --http://www.jb51.net/article/56047.htm 构造函数 void __construct ([ mixed $args [, $... ]] ) PHP 5 允行开发 ...

  7. MySQL 序列使用

    MySQL 序列使用 MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现. 本章我们将介绍如 ...

  8. phpstudy apache 刚启动便停止

    1.添加站点 2.重启服务 3.遇见问题 apache 刚启动,1秒钟中后就停止 4.解决问题 发现是自己添加的网站中包含中文路径的问题,建议不要在自己的网站目录下包含中文.

  9. 在VC6中使用ogre进行游戏开发

    微软公司开发的visual c++6.0堪称史上最易用.最成熟的开发工具.vc6以其小巧.轻便赢得了程序员的喜爱,以至于在VS大行其道的时代,很多程序员仍然使用vc6作为开发工具,vc6的欢迎性可见一 ...

  10. Oracle高级查询,事物,过程及函数

    一 数值函数 数值 abs,ceil,floor,round,trunc字符串 instr,substr SQL>SELECT 'ABS':'|| ABS(-12.3) FROM DUAL; 运 ...