深度優先搜索算法(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;
}