zoukankan      html  css  js  c++  java
  • 搜索------深度优先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("
    ");  
             }
        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(" ");         

                         }

     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; 

       }

  • 相关阅读:
    python+opencv 运行环境搭建
    centos 安装 FLEXPART
    centos 安装npm node
    USACO4.3 Street Race【分析】
    USACO4.3 Letter Game【枚举·细节】
    结构体封装高精度 大整数BigInt
    POJ3585 Accumulation Degree【换根dp】
    换根dp特征总结
    HDU2196 Computer【换根dp】
    CF1187E Tree Painting【换根dp】
  • 原文地址:https://www.cnblogs.com/2014acm/p/3888381.html
Copyright © 2011-2022 走看看