解法一:
一共有Cmn 种方案,因为要求从小到大输出,我们可以从1开始选,之后每次递增选取,假设要在1-4中选3个树,画递归搜索树:
从左到右,从上到下对该树遍历,最后一层的叶子节点即为方案数。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int path[i];
void dfs(int u,int start)//u表示层数,start表示当前要从第几个数开始搜
{
if(u>m)
{
for(int i=0;i<m;i++)
cout<<path[i]<<" ";
cout<<endl;
return;
}
else
{
//还未到达叶子节点,从当前数继续往下搜
for(int i=start;i<=n;i++)
{
path[i]=i;//把当前数加入路径
dfs(u+1,i+1);//因为我们是递增搜索,所以下一个数+1
path[i]=0;//回溯,这里采用覆盖的方式,可不用
}
}
}
int main()
{
cin>>n>>m;
dfs(1,1);
return 0;
}
解法二:
可以在实现指数型枚举基础在进行每一次选取时进行计数,当等于m时进行输出,最后构造出的递归搜索树有n层。
#include<iostream>
using namespace std;
int n,m;
int state[25];//用于记录n个数的状态,1表示选取,0表示未选
void dfs(int u,int sum)//u表示层数,sum表示当前已经选取的个数
{
if(sum+n-u<m) return;//n-u表示剩余可以选的个数,
//sum+n-u表示最后能否选到m个数
if(sum==m)
{
for(int k=0;k<n;k++)
{
if(state[k]==1)
cout<<state[k]<<" ";
}
cout<<endl;
return;
}
state[u]=1;//选取当前数
dfs(u+1,sum+1);
state[u]=0;//不选
dfs(u+1,sum);
}
int main()
{
cin>>n>>m;
dfs(0,0);//从第0层开始选
return 0;
}