以前很少做DFS的题,从今天得开始做了,从最简单的开始,没办法,底子太差了,看看别人觉得很自愧不如~
模板1:
void DFS(int k) //处理第k步
{ if(k==n) //已经处理到第n步,到达目的状态,输出结果
else //处理第k步
for (int i=1;i<=m;i++) //第k步中有m种可能
{ //处理第k步
DFS(k+1);//进入第k+1步
}
}
例:从1-m个数中取n个数全排列,其中n个可以重复。
#include<iostream>
using namespace std;
const int MAX=40;
int n,m,a[MAX];
int DFS(int cur)
{ if(cur==n)
{ for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
else
{ for(int i=1;i<=m;i++)
{ a[cur]=i;
DFS(cur+1);
}
}
}
int main()
{ cin>>m>>n;
DFS(0);
return 0;
}
例2:上面中n个不能重复
#include<iostream>
using namespace std;
const int MAX=40;
int n,m,a[MAX],visit[MAX];
int DFS(int cur)
{ if(cur==n)
{ for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
else
{ for(int i=1;i<=m;i++)
if(!visit[i])
{ a[cur]=i;
visit[i]=1;//确定该数是否已经被访问,访问后设为1
DFS(cur+1);
visit[i]=0;//记得还原,因为在下一次调用的时候它未被访问
}
}
}
int main()
{ cin>>m>>n;
DFS(0);
return 0;
}
例题3:在上题的条件中加且n个数必须是从小到大。
#include<iostream>
#include<cstring>
using namespace std;
const int MAX=40;
int n,m,a[MAX];
int DFS(int cur)
{ if(cur==n+1)
{ for(int i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
else
{ for(int i=a[cur-1]+1;i<=m-n+cur;i++) //起始的a[cur-1]+1原因显而易见,至于m-n+cur,因为规定了从小到大,所以i最多到这个数,打个比方:若是 m=5,n=3,那么第一个数不可能是4,5,这样个数不可能有3个,只是节省时间,可以直接<=m,对于m很小时。
{ a[cur]=i;
DFS(cur+1);
}
}
}
int main()
{ cin>>m>>n;
DFS(1);//从1开始的原因是数组a的原因,从DFS中可以看出a[cur-1],不从0开始得知
return 0;
}