c++算法之深搜 浅谈回溯与不回溯
c++算法之深搜 浅谈回溯与不回溯
- 先说理论上的(个人意见):需要回溯的题大多都是迷宫这一类的,对这一步所做的操作不确定,可操作可不操作的(就像迷宫,这一步到底走不走并不确定),要将操作在递归之后回溯一步;如果操作对象变量在深搜函数的参里,也可以在递归里写参的时候写在参里(举个例子吧,像dfs(c+1,sum++)等价于 sum++;dfs(c+1,sum);sum--;)因为带进参里实际上也没改变变量本身的值。而不需要回溯的题则是搜到之后确定要对它做操作的,之前的例子暂时没想到,就拿OpenJudge2.5的1388 Lake Counting来说,我们可以肯定找到一个‘W’后要标记,因为题目求的是总水塘的个数,如果回溯了就会重复计算。
- 后面谈一谈经历:搜索算法可以说是我学的第一个算法(高精度、递归、排序什么的是在前面讲基础的时候学的,搜索以后是正式步入算法),而回溯是我学的第一个搜索算法。回溯做的第一题是八皇后问题,后面涉及到素数环、拆数、全排列等等,都是按照回溯框架写的。当时觉得回溯就是长框架这个样子的。
- 后来做一些题的时候,发现回溯会超时,有的甚至严重到样例在下面运行的时候自己都发现慢。这个时候,老师就顺势推出了另一搜索算法:广度优先算法。广搜就是用来解决“最优解”“最短路径”“最快”等问题的有力武器。而当时觉得深搜(深度优先搜索)就是回溯。
- 而随着做题数越来越多,便碰到了一些不用回溯的题目,它们其它地方都跟回溯差不多,只有回溯的地方不一样,具体举不出来当时是哪道题了,只记得老师再讲这道题的时候说过:“那所以这里是不是不用回溯了”。当时激起了我的疑问,但却还不大在意这里。
- 其实很多东西的理解都是一点一点领悟到的,有的时候错过一些题,或是对着一些题目一头雾水之后就慢慢体悟到了它是怎么一回事(当然 OpenJudge1792那道纯属非智力因素,不在此例),题目做得越多就渐渐懂了。深搜跟回溯是不一样的。回溯是深搜没错,但是深搜并不一定要回溯。而且回溯也不一定必须严格按框架来,框架中改动一下也是可以的,最后判断到达目的地也可以提到最前面来,但是判断条件要+1什么的。
- 其实最深刻的一次还是搜索都快学完了,DP入门的时候,老师让我们先用深搜做DP题TLE之后,再结合DP理解。当时做到一道题一直没对,后面去问了才发现是递归的时候,当时那个同学说的是:要不增值就在递归的参数里面加,要不就回溯,不然会改变它的值。也许是积累已经到位,或是已经理解透彻,此后就明白了回溯与不回溯的关系,后面写博客的时候,相当于回顾了一遍题目,印象就更加深刻了。
- 很抱歉之前讲了这么久的故事,我只是想表达这样一个观点:很多时候理解不到或是理解不透彻一个知识点也是正常的,不必灰心丧气,做题的时候认真思考,留心一点,那么题量上去了有的地方自然茅塞顿开。这也告诉我们,做题是提升能力的重要关键。当然也不是说非得刷一堆,在保证质量的前提下(把题目弄懂,不放过任何一个细节,积极讨论,甚至达到可以和同学讲懂的境界),多多刷题,积累题量,才能由量变到质变。
转载请注明出处,有疑问欢迎探讨
博主邮箱 2775182058@qq.com
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现