枚举排列的核心思想:运用回溯法可以轻松解决排列问题,也可以应用到c++的STL中的next_permutation()函数,对于不同场景,不同的方法各有各的好处。
next_permutation(下一个排列法)代码展示:
#include<bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; vector<int>di; for(int i=0;i<n;i++){ int a; cin>>a; di.push_back(a); } while(next_permutation(di.begin(),di.end())){ //注意这里的操作 for(int i=0;i<di.size();i++){ cout<<di[i]<<‘ ‘; } cout<<endl; } }
回溯法求排列的代码展示:
#include<bits/stdc++.h> using namespace std; int n; vector<int>sum; int book[10000]; int sum2=0; void dfs(int step){ //step为枚举到第step位 , 故到达n+1就要返回 if(step>=(n+1)){ for(int i=0;i<sum.size();i++){ cout<<sum[i]<<‘ ‘; } sum2++; cout<<endl; return; } for(int i=1;i<=n;i++){ if(book[i]==0){ book[i]=1; sum.push_back(i); dfs(step+1); sum.pop_back(); // 回溯法 book[i]=0; } } return; } int main(){ cin>>n; dfs(1); cout<<sum2<<endl; }
求组合的核心思想:学过高中数学的都知道,排序是讲究顺序的,而组合是不讲求顺序的,因此我们只需要在求排列的回溯法上加上定序的技巧就可以敲出组合数了。
回溯法+定序求组合:
#include<bits/stdc++.h> using namespace std; int n,r; vector<int>a; void dfs(int i,int s[],int k){ //k为定序的技巧的开始的数 if(i==(r+1)){ for(int i=0;i<r;i++){ cout<<setw(3)<<a[i]; } cout<<‘\n‘; return; } for(int j=k;j<=n;j++){ //定序 a.push_back(s[j]); dfs(i+1,s,j+1); a.pop_back(); } } main(){ cin>>n>>r; int s[n+1]; for(int i=1;i<=n;i++){ s[i]=i; } dfs(1,s,1); }
输入输出样例:
输入: 5 3 输出: 1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5
原文:https://www.cnblogs.com/acmerhome/p/14789405.html