原题连接ios
从 1~n 这 n 个整数中随机选出 m 个,输出全部可能的选择方案。c++
两个整数 n,m ,在同一行用空格隔开。数组
按照从小到大的顺序输出全部方案,每行1个。优化
首先,同一行内的数升序排列,相邻两个数用一个空格隔开。spa
其次,对于两个不一样的行,对应下标的数一一比较,字典序较小的排在前面(例如1 3 5 7排在1 3 6 8前面)。code
n>0 ,
0≤m≤n ,
n+(n−m)≤25递归
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
思考题:若是要求使用非递归方法,该怎么作呢?ci
仍然是递归搜索树,枚举方案为:依次枚举每一个位置上的数是几;get
本题又用到剪枝来对代码进行了优化,若是发现某方案无解,则能够提早退出。string
dfs参数中:
1.表示m个位置,开一个数组存储env[N];
2.loc表示当前枚举到了哪一个位置;
3.sma当前最小能够从哪一个数枚举 。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; const int N = 29; int n,m; int env[N]; void dfs(int loc,int sma)//当前枚举到了哪一个位置、当前最小能够从哪一个数枚举 { //剪枝 if(loc+n-sma<m) return;//已经选了loc-1个数 假设把sma到n所有选上(n-sma+1)也不够m个数(<m) if(loc==m+1)//表示枚举结束 { for(int i=1;i<=m;i++) cout<<env[i]<<' '; cout<<endl; return; } for(int i=sma;i<=n;i++) { env[loc]=i; dfs(loc+1,i+1); env[loc]=0; } } int main() { cin>>n>>m; dfs(1,1);//初始从第1个位置开始枚举、最小能够枚举的数为1 return 0; }