回溯搜索算法初步(我终于发现博客里有插入代码功能)

回溯与搜索框架:

int search(int k){

  for(i = 1;i < 字符种数 i++){

    if(合法条件){

      存储数据;

      if(达成目标) 输出;

      else search(k+1);

    }

}

 

 

框架二:类比递归,把判断目标放在前面

 写搜索时,要先确定目标条件,再确定合法条件,不合法的跳过;深度优先搜索(DFS):从某顶点出发到达尽头停止,期间优先深度遍历,截止后回溯开始,直到达到条件(如所有节点访问完)

深度优先搜索框架:

int search(int k){

  for(i = 1;i < 字符种数 i++){

    if(合法条件){

      存储数据;

      if(达成目标) 输出;

      else search(k+1);

    }

}

 

 

例1:有1至n这些整数,从中任意取r个排列,打印排列及个数

目标条件:取出的数个数达到r

#include<bits/stdc++.h>
using namespace std;
int n,r,a[2022],num;
void print(){
    num++;
    for(int i = 1;i <= r;i++){
        printf("%d ",a[i]);
    }
    printf("\n");
}
void search(int pos){
    for(int i = 1;i <= n;i++){
        int j = 0;
        a[pos] = i;
        if(pos == r){
            print();
        }
        else{
            search(pos+1);
        }
        
    }
}

int main(){
    cout<<"input n,r:";
    cin>>n>>r;
    search(1);
    cout<<"number="<<num<<endl;
}

DFS搜索来解决这个问题:

#include<bits/stdc++.h>
using namespace std;
int n,r,a[20000];
void dfs(int x,int y){        //x为到达的数值,y为第几个数
    if(y > r){
        for(int i = 1;i <= r;i++){
            printf("%d ",a[i]);
        }
        printf("\n");
        return;
    }
    for(int i = x;i <= n;i++){
        a[y] = i;
        dfs(i + 1,y + 1);
    }
}
int main(){
    scanf("%d%d",&n,&r);
    dfs(1,1);
    return 0;
}

 

例2:自然数分解

目标条件:和达到目标自然数。合法条件:数大于前一个,小于当前剩下的和

 DFS:

#include<bits/stdc++.h>
using namespace std;
int a[20000],n;
void dfs(int x,int y,int z){   //y为当前和,x为上一个数,z拆分出的数字个数
    if(y > n) return;
    if(y == n){
        for(int i = 1;i < z;i++){
            if(i>1) printf("+");
            printf("%d",a[i]);
        }
        printf("\n");
        return;
    }
    for(int i = x;i < n;i++){
        
        a[z] = i;
        dfs(i,y+i,z+1);
        
        
    }
    
}

int main(){
    scanf("%d",&n);
    dfs(1,0,1);
    return 0;
}

 

上一篇:算法模板-深度优先遍历


下一篇:iOS Model Identifier(iOS 设备型号)