c++算法之深搜 浅谈回溯与不回溯

c++算法之深搜 浅谈回溯与不回溯

  • 先说理论上的(个人意见):需要回溯的题大多都是迷宫这一类的,对这一步所做的操作不确定,可操作可不操作的(就像迷宫,这一步到底走不走并不确定),要将操作在递归之后回溯一步;如果操作对象变量在深搜函数的参里,也可以在递归里写参的时候写在参里(举个例子吧,像dfs(c+1,sum++)等价于 sum++;dfs(c+1,sum);sum--;)因为带进参里实际上也没改变变量本身的值。而不需要回溯的题则是搜到之后确定要对它做操作的,之前的例子暂时没想到,就拿OpenJudge2.5的1388 Lake Counting来说,我们可以肯定找到一个‘W’后要标记,因为题目求的是总水塘的个数,如果回溯了就会重复计算。
  • 后面谈一谈经历:搜索算法可以说是我学的第一个算法(高精度、递归、排序什么的是在前面讲基础的时候学的,搜索以后是正式步入算法),而回溯是我学的第一个搜索算法。回溯做的第一题是八皇后问题,后面涉及到素数环、拆数、全排列等等,都是按照回溯框架写的。当时觉得回溯就是长框架这个样子的。
  • 后来做一些题的时候,发现回溯会超时,有的甚至严重到样例在下面运行的时候自己都发现慢。这个时候,老师就顺势推出了另一搜索算法:广度优先算法。广搜就是用来解决“最优解”“最短路径”“最快”等问题的有力武器。而当时觉得深搜(深度优先搜索)就是回溯。
  • 而随着做题数越来越多,便碰到了一些不用回溯的题目,它们其它地方都跟回溯差不多,只有回溯的地方不一样,具体举不出来当时是哪道题了,只记得老师再讲这道题的时候说过:“那所以这里是不是不用回溯了”。当时激起了我的疑问,但却还不大在意这里。
  • 其实很多东西的理解都是一点一点领悟到的,有的时候错过一些题,或是对着一些题目一头雾水之后就慢慢体悟到了它是怎么一回事(当然 OpenJudge1792那道纯属非智力因素,不在此例),题目做得越多就渐渐懂了。深搜跟回溯是不一样的。回溯是深搜没错,但是深搜并不一定要回溯。而且回溯也不一定必须严格按框架来,框架中改动一下也是可以的,最后判断到达目的地也可以提到最前面来,但是判断条件要+1什么的。
  • 其实最深刻的一次还是搜索都快学完了,DP入门的时候,老师让我们先用深搜做DP题TLE之后,再结合DP理解。当时做到一道题一直没对,后面去问了才发现是递归的时候,当时那个同学说的是:要不增值就在递归的参数里面加,要不就回溯,不然会改变它的值。也许是积累已经到位,或是已经理解透彻,此后就明白了回溯与不回溯的关系,后面写博客的时候,相当于回顾了一遍题目,印象就更加深刻了。
  • 很抱歉之前讲了这么久的故事,我只是想表达这样一个观点:很多时候理解不到或是理解不透彻一个知识点也是正常的,不必灰心丧气,做题的时候认真思考,留心一点,那么题量上去了有的地方自然茅塞顿开。这也告诉我们,做题是提升能力的重要关键。当然也不是说非得刷一堆,在保证质量的前提下(把题目弄懂,不放过任何一个细节,积极讨论,甚至达到可以和同学讲懂的境界),多多刷题,积累题量,才能由量变到质变。

你可能感兴趣的:(搜索-暴力DFS,随笔)