从n个数(a[N])中有序挑m个数(b[N])。
例如 从5个数中选4个数字
输入
5 4
1 2 3 4 5
输出
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5
每次记录一个last,表示本次选择数的下标,下一次选数就要从下标大于last的开始选.
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000;
int a[N],b[N];
int n,m;
void dfs(int u,int last){
if(u==m){
for(int i=0;i<m;i++)
printf("%d ",b[i]);
puts("");
return;
}
for(int i=0;i<n;i++){
if(u==0||(u>0&&i>last)){
b[u]=a[i];
last=i;
dfs(u+1,last);
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
dfs(0,0);
return 0;
}
优化一点,既然每次都从下标大于last的开始选,下i就从last+1开始迭代,
void dfs2(int u,int last){
if(u==m){
for(int i=0;i<m;i++)
printf("%d ",b[i]);
puts("");
return;
}
for(int i=last+1;i<n;i++){
b[u]=a[i];
last=i;
dfs(u+1,last);
}
}
但是这样u=0时,i就会从1开始迭代,显然不合理,所以last一开设为-1;
dfs2(0,-1);
或者
void dfs2(int u,int last){
if(u==m){
for(int i=0;i<m;i++)
printf("%d ",b[i]);
puts("");
return;
}
if(u==0)
last--;
for(int i=last+1;i<n;i++){
b[u]=a[i];
last=i;
dfs(u+1,last);
}
}
附源码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000;
int a[N],b[N];
int n,m;
void dfs(int u,int last){
if(u==m){
for(int i=0;i<m;i++)
printf("%d ",b[i]);
puts("");
return;
}
for(int i=0;i<n;i++){
if(u==0||(u>0&&i>last)){
b[u]=a[i];
last=i;
dfs(u+1,last);
}
}
}
void dfs2(int u,int last){
if(u==m){
for(int i=0;i<m;i++)
printf("%d ",b[i]);
puts("");
return;
}
if(u==0)
last--;
for(int i=last+1;i<n;i++){
b[u]=a[i];
last=i;
dfs(u+1,last);
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
// dfs(0,0);
// dfs2(0,0);
return 0;
}