搜索------深度优先DFS-----模板1:例1 例2 例3 例4

 

深度优先(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;       }
View Code

 

//从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;
}
View Code

#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;
}
View Code

 

#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;
}
View Code

 

#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;       }
View Code

 

#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;    
}
View Code

 

 

//从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;    
}
View Code

//从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("\n");  
         }
    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个数开始
 }
View Code

 

 

 

#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("\n");         

                     }

 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;    
}
View Code

 

 

#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; 

   }

 

posted @ 2014-08-03 14:42  2014acm  阅读(280)  评论(0编辑  收藏  举报