[dfs入門]全排列問題
阿新 • • 發佈:2021-08-04
first:題目
描述
輸出自然數\(1\)到\(n\)所有不重複的排列,即\(n\)的全排列,要求所產生的任一數字序列中不允許出現重複的數字。
輸入
輸入一個數字\(n(1≤n≤9)\)
輸出
由\(1\)~\(n\)組成的所有不重複的數字序列,每行一個序列。
second:分析
直接遞迴即可。
設\(dep\)代表列舉的深度,即第\(dep\)個數應該放什麼,再一一列舉,如果這個數沒有用到,則使用,然後列舉下一層,結束後再列舉下一個數。
當全部列舉完後,即\(dep=n+1\)時,輸出,時間複雜度為\(O(n\ !)\)
third:新知
我們可以開一個\(bool\)陣列來判斷是否列舉,如果為\(false\)
列舉時,我們先判斷有沒有用,如果沒有用過,就加入,並且這個數變成\(true\),遞迴下一層。
當這個數遞迴完以後,再把這個數變成\(true\),繼續列舉,這叫做回溯法。
fourth:注意
1、為了不重複,要設陣列表示狀態。
2、及時回溯,以便下次搜尋。
3、當搜到第\(n+1\)次時,代表全部搜好了,然後輸出。
fifth:程式碼
#include<bits/stdc++.h> using namespace std; int n; int a[101]; bool node[101]; void write() { for(int i=1;i<=n;i++) { cout<<a[i]<<" "; } cout<<endl;//輸出 } void dfs(int dep) { if(dep==n+1)//搜尋完了 { write(); return; } for(int i=1;i<=n;i++) { if(node[i]==false)//沒有用過 { a[dep]=i; node[i]=true;//使用 dfs(dep+1);//下一個數 node[i]=false;//回溯 } } } int main() { cin>>n; dfs(1);//從第一層開始 return 0; }