一. 题目
二. 理论
规定每一行升序去选, 保证去除冗余同时字典序最小
若已选的加上剩余可选的不足m直接剪枝即可
三. 代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N=30;
int n, m;
class Search
{
public:
int path[N];//存储选择方案
public:
void initIO()
{
// 关闭输入输出缓存,使效率提升
ios::sync_with_stdio(false);
// 解除cin和cout的默认绑定,来降低IO的负担使效率提升
cin.tie(nullptr);
cout.tie(nullptr);
}
Search()
{
initIO();
fill(path, path+N, 0);
}
/**
* 搜索函数
* @param u 表示选了几个
* @param st 每层开始选的起点,保证字典序,同时排除重复选法(不考虑顺序)
*/
void dfs(int u, int st)
{
//选了u个+上剩余可选的不足m时, 直接结束递归
if(u+n-st+1<m) return;
if(u==m)//选够m个
{
for(int i=0;i<m;++i)
cout<<path[i]<<" ";
cout<<endl;
return;
}
for(int i=st;i<=n;++i)
{
path[u]=i;
dfs(u+1, i+1);
}
}
}s;
int main()
{
cin>>n>>m;
s.dfs(0, 1);//最开始可选m个数
}