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

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

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

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

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

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

关于穷举法,可以说是计算机领域最为人熟知但却有大大忽略的一种基础算法了。很多人都会知道,它的思想就是将解空间给一一列举出来然后进行计数或者其他的什么操作。有较好算法基础的人会知道,搜索(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. python与数值计算环境搭建

    数值计算的编程的软件很多种,也见过一些编程绘图软件的对比. 利用Python进行数值计算,需要用到numpy(矩阵) ,scipy(公式符号), matplotlib(绘图)这些工具包. 1.Linu ...

  2. android requestWindowFeature使用详解

    requestWindowFeature可以设置的值有:          1.DEFAULT_FEATURES:系统默认状态,一般不需要指定          2.FEATURE_CONTEXT_M ...

  3. htm5 user-scalable 的意思

    <meta name="viewport" content="width=device-width,user-scalable=yes,minimum-scale= ...

  4. C# 自定义线程修改UI(一)

    在Wpf中界面显示数据的修改,都是通过UI线程完成,如果尝试从其他线程中直接修改控件的值回抛出异常,“调用线程无法访问此对象,因为另一个线程拥有该对象”. 例如:http://www.cnblogs. ...

  5. sql - 面试

    一,关于 group by 表内容: 2005-05-09 胜 2005-05-09 胜 2005-05-09 负 2005-05-09 负 2005-05-10 胜 2005-05-10 负 200 ...

  6. centos6 x86 安装 oracle 11g2r 日志

    一.安装centos 6.5 二.安装ora所需的库 三.修改centos内核 四.建用户组和目录结构等 五.安装ora11g2r 六.安装sqlplus的翻页程序和help补丁 七.自启动脚本 八. ...

  7. 【USACO 1.4.2】时钟

    [题目描述] 考虑将如此安排在一个 3 x 3 行列中的九个时钟: |-------| |-------| |-------| | | | | | | | |---O | |---O | | O | ...

  8. equals和hashcode

    java当中所有的类都继承于Object这个基类,在object中的基类定义了一个equals方法,public boolean equals(Object obj) {     return (th ...

  9. 页面添加 mask 遮罩层

    var mask = function(){ $('<div>').css({ position: 'fixed', left: 0, top: 0, width: '100%', hei ...

  10. VBoxManage 命令行使用

    原文地址:http://cnjun939.blog.163.com/blog/static/78144538201251474311135/ 由于最近需研究virtualbox,看好看到上面的网址有, ...