深度优先(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:多重排列问题
输出1-m个数中取n个数的所有多重排列。例如n=2,m=3的所有多重排列为:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3

//从1到m中取n个数,允许重复取数 #include <iostream> using namespace std; int n,m, a[10]; void DFS(int k) { if (k==n) { for (int i=0; i<n; i++) cout<<a[i]<<" "; cout<<endl; } else for (int i=1; i<=m; i++) { a[k]=i; DFS(k+1); } } int main() { cin>>m>>n; DFS(0); return 0; }
//从1到m中取n个数,允许重复取数
#include <iostream>
using namespace std;
int n,m, a[10];
void DFS(int k)
{ if (k==n)
{ for (int i=0; i<n; i++)
cout<<a[i]<<" "; cout<<endl; }
else
for (int i=1; i<=m; i++)
{ a[k]=i; DFS(k+1); }
}
int main()
{
cin>>m>>n;
DFS(0);
return 0;
}

#include <iostream> using namespace std; int main(int argc, char *argv[]) { int i,j,k; for(i=1;i<=4;i++) for(j=1;j<=4;j++) for(k=1;k<=4;k++) cout<<i<<" "<<j<<" "<<k<<" "<<endl; return 0; }
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i,j,k;
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
for(k=1;k<=4;k++)
cout<<i<<" "<<j<<" "<<k<<" "<<endl;
return 0;
}

#include <iostream> using namespace std; int main(int argc, char *argv[]) { int i,j,k; int m; cin>>m ; for(i=1;i<=m;i++) for(j=1;j<=m;j++) for(k=1;k<=m;k++) cout<<i<<" "<<j<<" "<<k<<" "<<endl; return 0; }
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int i,j,k;
int m;
cin>>m ;
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
for(k=1;k<=m;k++)
cout<<i<<" "<<j<<" "<<k<<" "<<endl;
return 0;
}
例2:排列问题
输出1-m个数中取n个数的所有排列。例如n=2,m=3的所有排列为:
1 2
1 3
2 1
2 3
3 1
3 2
int used(int x,int y)

#include <iostream> using namespace std; int n,m,a[10]; int used(int x,int y) { int j; for(j=0;j<x;j++) if(a[j]==y) return 1; return 0; } void DFS(int k) { if(n==k) { for(int i=0;i<n;i++) cout<<a[i]<<" "; cout<<endl; } else for(int i=1;i<=m;i++) if(!used(k,i)) { a[k]=i;DFS(k+1); } } int main(int argc, char *argv[]) { cin>>m>>n; DFS(0); return 0; }
#include <iostream>
using namespace std;
int n,m,a[10];
int used(int x,int y)
{
int j;
for(j=0;j<x;j++)
if(a[j]==y) return 1;
return 0;
}
void DFS(int k)
{
if(n==k)
{ for(int i=0;i<n;i++) cout<<a[i]<<" ";
cout<<endl;
}
else
for(int i=1;i<=m;i++)
if(!used(k,i)) // if(used(k,i)==0)
{
a[k]=i;DFS(k+1);
}
}
int main(int argc, char *argv[])
{
cin>>m>>n; DFS(0);
return 0;
}
*******************************************************************8
加标志 bz[10 ]-------------回溯法,较快

#include <iostream> using namespace std; int n,m, a[10]; // bool bz[10]={0}; bool bz[10]; void DFS(int k) { if (k==n) { for (int i=0; i<n; i++) cout<<a[i]<<" "; cout<<endl; } else for (int i=1; i<=m; i++) if ( !bz[i] ) { a[k]=i; bz[i]=true; DFS(k+1); bz[i]=false;} } int main() { cin>>m>>n; DFS(0); return 0; }
#include <iostream>
using namespace std;
int n,m, a[10]; // bool bz[10]={0};
bool bz[10];
void DFS(int k)
{ if (k==n)
{ for (int i=0; i<n; i++) cout<<a[i]<<" ";
cout<<endl;
}
else
for (int i=1; i<=m; i++)
if ( !bz[i] )
{ a[k]=i; bz[i]=true; DFS(k+1); bz[i]=false;}
}
int main()
{ cin>>m>>n; DFS(0); return 0; }
#include <iostream>
using namespace std;
int n,m, a[10]; // bool bz[10]={0}; //全局变量
bool bz[10];
void DFS(int k)
{ if (k==n)
{ for (int i=0; i<n; i++) cout<<a[i]<<" ";
cout<<endl;
}
else
for (int i=1; i<=m; i++)
if ( !bz[i] )
{ a[k]=i; bz[i]=true; DFS(k+1); bz[i]=false;}
}
int main()
{ while( cin>>m>>n)
DFS(0);
return 0;
}
#include <iostream>
#include<cstring>
using namespace std;
int n,m, a[10];
bool bz[10]; // bool bz[10]={0};
void DFS(int k)
{ if (k==n)
{ for (int i=0; i<n; i++)
cout<<a[i]<<" ";
cout<<endl;
}
else
for (int i=1; i<=m; i++)
if ( !bz[i] ) { a[k]=i; bz[i]=true; DFS(k+1); bz[i]=false; }
}
int main()
{
memset(bz,0,sizeof(bz)); // 将数组中 所有的值 都清为0
while( cin>>m>>n)
DFS(0);
return 0;
}
*********************************************************88

//从1到m中取n个数,不允许重复取数,即排列方法2 #include <iostream> using namespace std; int n,m, a[10]; void DFS(int k) { if (k==n) { for (int i=0; i<n; i++) cout<<a[i]<<" "; cout<<endl; } else for (int i=1; i<=m; i++) { int ok=1; for (int j=0; j<k; j++) if ( a[j]==i )ok=0; if ( ok ) { a[k]=i;DFS(k+1); } } } int main() { cin>>m>>n; for (int i=0; i<m; i++) a[i]=i+1; DFS(0); return 0; }
//从1到m中取n个数,不允许重复取数,即排列方法2
#include <iostream>
using namespace std;
int n,m, a[10];
void DFS(int k)
{ if (k==n)
{ for (int i=0; i<n; i++) cout<<a[i]<<" ";
cout<<endl;
}
else for (int i=1; i<=m; i++)
{ int ok=1;
for (int j=0; j<k; j++) if ( a[j]==i )ok=0;
if ( ok ) { a[k]=i;DFS(k+1); }
}
}
int main()
{ cin>>m>>n;
DFS(0); return 0;
}

//从1到m中取n个数,不允许重复取数,即排列方法3 #include <iostream> using namespace std; int n,m, a[10]; void DFS(int k) { if (k==n) { for (int i=0; i<n; i++) cout<<a[i]<<" "; cout<<endl; } else for (int i=k; i<m; i++) { int t=a[k];a[k]=a[i];a[i]=t; DFS(k+1); t=a[k];a[k]=a[i];a[i]=t; } } int main() { cin>>m>>n; for (int i=0; i<m; i++) a[i]=i+1; DFS(0); return 0; }
//从1到m中取n个数,不允许重复取数,即排列方法3
#include <iostream>
using namespace std;
int n,m, a[10];
void DFS(int k)
{ if (k==n)
{ for (int i=0; i<n; i++) cout<<a[i]<<" ";
cout<<endl;
}
else
for (int i=k; i<m; i++)
{ int t=a[k];a[k]=a[i];a[i]=t;
DFS(k+1);
t=a[k];a[k]=a[i];a[i]=t; }
}
int main()
{ cin>>m>>n;
for (int i=0; i<m; i++) a[i]=i+1;
DFS(0); return 0;
}
********************************************************************************************************************************************
***********************************************************************************************************************************************
例3:组合问题
输出m个数中取n个数的所有组合。
例如m=5,n=3的所有组合为:
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5

#include<iostream> using namespace std; int m,n,a[10]; //存放每个数 void comb(int k) { if ( k>n ) { for (int i=1; i<=n;i++)printf("%5d",a[i]); printf(" "); } else for (int i=a[k-1]+1; i<=m-n+k; i++) { a[k]=i; comb(k+1); } } int main( ) { scanf("%d%d",&m,&n); comb(1); //从第1个数开始 }
#include<iostream>
using namespace std;
int m,n,a[10]; //存放每个数
void comb(int k)
{
if ( k>n )
{ for (int i=1; i<=n;i++) printf("%5d",a[i]); printf(" ");
}
else
for (int i=a[k-1]+1; i<=m-n+k; i++)
{ a[k]=i; comb(k+1); }
}
int main( )
{
scanf("%d%d",&m,&n);
comb(1); //从第1个数开始
}
例4:子集问题
给定一个有m个元素的集合,输出它所有可能的子集(共2m个)。
例如3个数1、2、3的所有子集为:
空集
1
1 2
1 3
1 2 3
2
2 3
3

#include<iostream> using namespace std; int m,n,a[10]; //存放每个数 void DFS(int k) { for (int i=0; i<k; i++) cout<<a[i]<<" "; cout<<endl; int min = k>a[k-1]+1 ? k : a[k-1]+1; for (int i=min; i<=m; i++) { a[k]=i; DFS(k+1); } } int main() { cin>>m; for (int i=0; i<m; i++) a[i]=i+1; DFS(0); return 0; }
#include<iostream>
using namespace std;
int m,n,a[10]; //存放每个数
void DFS(int k)
{
for (int i=0; i<k; i++) cout<<a[i]<<" "; cout<<endl;
int min = k>a[k-1]+1 ? k : a[k-1]+1;
for (int i=min; i<=m; i++)
{ a[k]=i; DFS(k+1); }
}
int main()
{
cin>>m;
for (int i=0; i<m; i++)
a[i]=i+1;
DFS(0);
return 0;
}