基本思路,是保存之前已经组合中,用到的最后一个下标位置,从该位置后来枚举,递归的完成组合。
若给出的初始序列有序,则组合给出的是按字典序的
在枚举的部分有一个小的剪枝。
//pre初始给0,求C(p,k),sel保存组合好的内容,yuan保存原数组
void zuHe(int pre,int p,int k,vector<int>& sel,vector<int>& yuan)
{
//sel.size()相当于深度
int dep = sel.size();
if(dep == k)
{
//do something
go(sel);
return;
}
//这里i<p也可,但如下写法可以剪枝
for(int i=pre;i<=p-k+dep;i++)
{
sel.push_back(yuan[i]);
zuHe(i+1,p,k,sel,yuan);
sel.pop_back();
}
}
下面给出一个使用样例
Sample Input
5 3
1 2 3 4 5
Sample Output
123
124
125
134
135
145
234
235
245
345
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> vec,now;
void go(vector<int>& sel);
int n,m;
//pre初始给0,求C(p,k),sel保存组合好的内容,yuan保存原数组
void zuHe(int pre,int p,int k,vector<int>& sel,vector<int>& yuan)
{
//sel.size()相当于深度
int dep = sel.size();
if(dep == k)
{
//do something
go(sel);
return;
}
//这里i<p也可,但如下写法可以剪枝
for(int i=pre;i<=p-k+dep;i++)
{
sel.push_back(yuan[i]);
zuHe(i+1,p,k,sel,yuan);
sel.pop_back();
}
}
void go(vector<int>& sel)
{
for(int i=0;i<sel.size();i++)
{
cout<<sel[i]<<' ';
}
puts("");
}
int main()
{
cin>>n>>m;
for(int i = 0;i<n;i++)
{
int tmp;
cin>>tmp;
vec.push_back(tmp);
}
zuHe(0,n,m,now,vec);
return 0;
}