博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
回溯枚举法
阅读量:5791 次
发布时间:2019-06-18

本文共 2878 字,大约阅读时间需要 9 分钟。

         回溯法也称试探法,它可以系统的搜索一个问题的所有解或者任意解。

         回溯法是一个既带有系统性又带有跳跃性的的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点

出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过

对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜索。回溯法在用来

求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。而回溯法在用来求问题的任一解时,只要搜索到问题

的一个解就可以结束。这种以深度优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题.

        针对所给问题,一般的解题步骤为:确定问题的解空间 --> 确定结点的扩展搜索规则--> 以DFS方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

Prime ring problem

 

题目描述

 

A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime. 
Note: the number of first circle should always be 1. 
 

输入描述:

n (0 < n < 20).

输出描述:

The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.       You are to write a program that completes above process.       Print a blank line after each case.
示例1

输入

68

输出

Case 1:1 4 3 2 5 61 6 5 2 3 4Case 2:1 2 3 8 5 6 7 41 2 5 8 3 4 7 61 4 7 6 5 8 3 21 6 7 4 3 8 5 2    这道题是素数环问题,大意是由给定的1到n数字中,将数字依次填入环中,使得环中任意两个相邻的数字间的和为素数。 对于给定的n,按字典序由小到大输出所有符合条件的解(第一个数恒定为1)    在这里可以采用回溯法枚举每一个值。当第一个数位为1确定时,尝试放入第二个数,使其与1的和为素数,放入后再尝试 放入第三个数,使其与第二个数的和为素数,直到所有的数全部放入环中,且最后一个数与1的和也是素数,则得到答案,输出。 若在尝试放数的过程中,发现当前位置无论放置任何之前未被使用的数均不可能满足条件,那么回溯改变其上一个数,直到产生 所需要的答案或不存在更多的解。
1 #include
2 #include
3 4 int ans[22]; //保存环中被放入的数 5 int mark[22]; //标记之前被放入环中的数 6 int n; 7 int prime[]={
2,3,5,7,11,13,17,19,23,29,31,37};//40内得素数,用于判断是否是素数 8 9 int Judge( int x)10 {11 //判断一个数是否是素数12 int i;13 for( i=0; i<12; i++){14 if( prime[i]==x) return 1;15 }16 return 0;17 }18 19 void Check()20 {21 //检查输出由回溯法枚举得到的解22 int i;23 if( Judge(ans[n]+ans[1])==0) return;//判断最后一个数与第一个数的和是否是素数24 for( i=1; i<=n; i++){25 if( i!=1) printf(" ");26 printf("%d",ans[i]);27 }28 printf("\n");29 }30 31 void DFS( int num)32 {33 //递归枚举,num为当前已经放入环中的数字34 int i;35 if( num>1 ) if( Judge(ans[num]+ans[num-1])==0 ) return;36 37 if( num==n ){38 //若已经放入n个数39 Check();40 return;41 }42 for( i=2; i<=n; i++){43 if(mark[i]==0){44 mark[i]=1; //标记i为已经使用45 ans[num+1] = i; //将这个数字放入ans数组中46 DFS( num+1 );47 mark[i] = 0; //重新标记为未使用48 }49 }50 }51 52 int main()53 {54 int cnt=0; //记录case数55 int i;56 while( scanf("%d",&n)!=EOF){57 cnt++;58 for( i=0; i<22; i++) mark[i] = 0; //初始化59 ans[1] = 1;60 printf("Case %d:\n",cnt);61 mark[1] = 1;62 DFS(1);63 printf("\n");64 }65 return 0;66 }

 

 

 

转载于:https://www.cnblogs.com/yuxiaoba/p/8452794.html

你可能感兴趣的文章
使用代码获得Netweaver里某个software component和C4C的版本
查看>>
深入理解Plasma(2):Plasma 细节剖析
查看>>
vue-devtools在Chrom浏览器上的安装
查看>>
全球首款社交用机器人Jibo将走入历史舞台
查看>>
阿里云发布边缘节点服务2.0,建立“融合、开放、联动”的边缘计算新形态
查看>>
提供SaaS Launchkit,快速定制,一云多端等能力,一云多端将通过小程序云实现...
查看>>
[Java学习探讨]为什么学Java虚拟机的Java程序员更值钱?
查看>>
HashTable
查看>>
Index 和Index Type 的区别
查看>>
转换wav为采样率16000的wav
查看>>
SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
查看>>
整合企业架构的技术点
查看>>
Java编程代码性能优化总结
查看>>
深度解析JavaScript事件对象
查看>>
用Python爬取优酷弹幕数据并做成词云,"人"云亦云
查看>>
外企面试,哪有你想象的那么难!(已收埃森哲、NTTDATA等8家外企offer)
查看>>
华为云服务器实战 之 Gitlab安装与配置使用
查看>>
数据库性能测试
查看>>
MongoDB
查看>>
OSChina 周日乱弹——如何请假不被老板骂
查看>>