深度优先搜索算法(Depth-First-Search)
:是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。
思想:一直往深处走,直到找到解或者走不下去为止
主要步骤:
1.构建一个递归函数,函数参数应该最起码包括题目需求使用的参数
2.找到边界,递归函数里首先列出递归结束的条件,即满足要求或者超出范围
3.接着列出所有可能移动或者变化的路径
void dfs(int step,...)
{
if(走不下去了) // 判断边界
{
相应操作;
}
// 枚举每一种可能
if(满足条件) dfs(step+1,...);
if(满足条件) dfs(step-2,...);
}
例题:
一,李白打酒
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
注意:通过浏览器提交答案。答案是个整数。不要书写任何多余的内容。
分析:运用DFS算法,当遇见店时酒乘一倍,遇见花时酒减1,直到店和花都为0时,输出酒的数值。
#include <iostream>
using namespace std;
int ans=0;
void dfs(int dian,int hua,int jiu){
if(dian==0 && hua==0 && jiu==1){//出口
ans++;
}
//枚举可能情况
if(dian>0) dfs(dian-1,hua,jiu*2);
if(hua>0) dfs(dian,hua-1,jiu-1);
}
int main(){
int n;
dfs(5,9,2);
cout<<ans;
return 0;
}
答案:14
二,第39级台阶
小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!
站在台阶前,他突然又想着一个问题:
如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?
请你利用计算机的优势,帮助小明寻找答案。
要求提交的是一个整数。
注意:不要提交解答过程,或其它的辅助说明文字。
分析:运用DFS算法
#include <iostream>
using namespace std;
int ans;
void f(int n,int step){//n:剩下的阶梯数 step:已走的步数
if(n<0)//错误走法
return;
if(n==0&&step%2==0){//阶梯数走完且步数为偶数
ans++;
}
f(n-1,step+1);//一步迈上1个台阶
f(n-2,step+1);//一步迈上2个台阶
}
int main()
{
f(39,0);
cout<<ans<<endl;
return 0;
}
答案:51167078