学习算法,编程之路

原创 2015年11月21日 12:43:35

回溯法

目录

回溯法:抽象出来是深根遍历的方法,在递归构造中,生成和检查可以有机的结合起来,从而减小不必要的枚举。回溯法应用范围很广,只要能把带求解的问题分成不太多的步骤,每个步骤有只有不太多的选择,都可以考虑应用回溯法。

回溯法函数模板(自我总结):

      void dfs(int cur){
        if (cur==N){
            //将当前所求解输出
            tot++;//表示解的个数,初始化为0;
          }
         else
             for(顺序查找可能的候选值){
                  if(满足条件){
                        C[cur]被赋值;
                        //vis[i]=1;已被访问
                        dfs(cur+1);
                        //vis[i]=0;还原未被访问状态
                    }
               }

      }

列举两个例子

1.求解八皇后问题

  题目:棋盘上放置8个皇后,使得她们相互不攻击,此时每个皇后的攻击范围为同行同列同对角线,
要求找出所有的解。
解的表示输出N位整数(1,2,3,,N)的所有满足要求的排列;
void dfs(int cur){
    int i,ok,j;
    if(cur==N){
        for(i=0;i<N;i++)
            printf("%d ",C[i]);
        printf("\n");
        tot++;
    }
    else 
        for(i=1;i<=N;i++){
            ok=1;
            for(j=0;j<cur;j++){
                if(C[j]==i||C[j]+j==i+cur||C[j]-j==i-cur){//不在同行同列同对角线
                    ok=0;break;
                }
            }
            if(ok){
                C[cur]=i;
                dfs(cur+1);
            }
        }


}

2.回溯法求解素数环

题目:输入正整数n,把整数1,2,3,4,…,n组成一个环,使得相邻两个整数之间的和均为素数。
输出是从1开始逆时针输出,同一个环应恰好输出一次。n<=16;

该程序运行结果非常完美,当输入为16时,你会看到精彩的运行结果,何不试试呢?
(个人对此题有另外的理解:素数环有个特点,就是奇偶相间,
相邻的两个数必须一个是奇数另一个是偶数,输入的n必须是偶数,才能有解,否者无解。
各位大虾,能否按这个思路写出一个更加简洁的算法程序?)

实验测试用时,n=16,time=41s;
void dfs(int cur){
    int i;
    if(cur==n&&isp[C[cur-1]+C[0]])
    {   for( i=0;i<n;i++){
            printf("%d ",C[i]);
        }
        tot++;
        printf("\n");
    }
    else for( i=2;i<=n;i++){
        if(vis[i]==0&&isp[C[cur-1]+i]){
            C[cur]=i;
            vis[i]=1;
            dfs(cur+1);
            vis[i]=0;
        }
    }
}

运行截图

1.八皇后求解
八皇后求解
2.素数环,n=6时,解
这里写图片描述

源代码

八皇后问题:

#include<stdio.h>
#include<stdlib.h>
#define N 8//N 表示皇后的个数
int C[N],tot=0;

void dfs(int cur){
    int i,ok,j;
    if(cur==N){
        for(i=0;i<N;i++)
            printf("%d ",C[i]);
        printf("\n");
        tot++;
    }
    else 
        for(i=1;i<=N;i++){
            ok=1;
            for(j=0;j<cur;j++){
                if(C[j]==i||C[j]+j==i+cur||C[j]-j==i-cur){//不在同行同列同对角线
                    ok=0;break;
                }
            }
            if(ok){
                C[cur]=i;
                dfs(cur+1);
            }
        }


}
int main(){
    int cur=0;
    dfs(cur);
    printf("tot=%d\n",tot);
    return 0;

}

素数环求解

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 20
int C[N],isp[2*N],vis[N];
int tot,n;


int isprime(int b){
    int i;
    if(b<=3)return 1;
    for(i=2;i*i<=b;i++){
        if(b%i==0)return 0;
    }
    return 1;

}

void dfs(int cur){
    int i;
    if(cur==n&&isp[C[cur-1]+C[0]])
    {   for( i=0;i<n;i++){
            printf("%d ",C[i]);
        }
        tot++;
        printf("\n");
    }
    else for( i=2;i<=n;i++){
        if(vis[i]==0&&isp[C[cur-1]+i]){
            C[cur]=i;
            vis[i]=1;
            dfs(cur+1);
            vis[i]=0;
        }
    }
}
int main(){
    int i,cur;

    memset(vis,0,sizeof(vis));//include<string.h>
    scanf("%d",&n);
    for(i=1;i<2*N;i++){
        isp[i]=isprime(i);
    }
    tot=0;
    cur=1;
    C[0]=1;
    dfs(cur);
    printf("tot=%d",tot);
    return 0;
}

以上是个人的学习心得,若有不当之处,还请多多指教。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

学习算法,编程之路

基于Merkle Tree 的挑战应答环节上一节,说到MerkleTree的建立,是基于文件分块,对分块进行哈希,用对应的哈希值作为MerkleTree的叶子节点。计算父亲节点=两个孩子节点哈希值的连...

学习算法,编程之路

MerKle Tree的建立merkle tree 的基本概念:Merkle Tree 是由计算机科学家 Ralph Merkle 在很多年前提出的,并以他本人的名字来命名。不过,Merkle Tre...

十大编程算法助程序员走上高手之路

十大编程算法助程序员走上高手之路   算法一:快速排序算法   快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n...

十大编程算法助程序员走上高手之路

十大编程算法助程序员走上高手之路

十大编程算法助程序员走上高手之路

算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速...

十大编程算法助程序员走上高手之路

算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速...

十大编程算法助程序员走上高手之路

算法一:快速排序算法 快速排序是由东尼霍尔所发展的一种排序算法。在平均状况下,排序个项目要次比较。在最坏状况下则需要次比较,但这种状况并不常见。事实上,快速排序通常明显比其他算法更快,因为它...

十大编程算法助程序员走上高手之路

算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比 较,但这种状况并不常见。事实上,快...

十大编程算法助程序员走上高手之路

算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快...

十大编程算法助程序员走上高手之路

算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)