1. DFS生成排列

众所周知,1,2…n的排列一共有n!个,因此生成全排列至少需要n!的时间复杂度。如果用循环来生成排列,当n稍大时,内外循环会非常之多。可以用DFS模拟解决,生成0 … n-1的排列的代码如下:

void dfs(int depth)
{
int i,length;
if(depth==n) //n个数排列完毕
{
print the result
return;
} for(i=0;i<n;i++)
if(!visit[i]) //点i没被访问
{
visit[i]=1;
result[depth]=i;
dfs(depth+1); //进入下一次递归
visit[i]=0; //回溯,将点i重新标记为未被访问
}
}

2. 问题

2.1 POJ 2907

题目大意:从start点出发,经过n个beeper点后,回到start点;求最短路径。

思路:由于n<=10,可以用全排列解决。将n个beeper点排列,所得的序列即为经过beeper点的先后顺序,然后计算路径长度。在这n!个路径中,找出最小值。

源代码:

2907 Accepted 164K 0MS C 1127B 2013-10-10 21:16:22
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "limits.h" typedef struct position
{
int x,y;
}Position; int n,minimum,result[10],visit[10];
Position start,beeper[10]; int distance(Position a,Position b)
{
return abs(a.x-b.x)+abs(a.y-b.y);
} void dfs(int depth)
{
int i,length;
if(depth==n)
{
length=0;
for(i=1;i<n;i++)
length+=distance(beeper[result[i]],beeper[result[i-1]]);
length+=distance(beeper[result[0]],start);
length+=distance(beeper[result[n-1]],start);
if(length<minimum)
minimum=length;
return;
} for(i=0;i<n;i++)
if(!visit[i])
{
visit[i]=1;
result[depth]=i;
dfs(depth+1);
visit[i]=0;
}
} int main()
{
int scenarios,xsize,ysize,i;
scanf("%d",&scenarios);
while(scenarios--)
{
scanf("%d%d",&xsize,&ysize);
scanf("%d%d%d",&start.x,&start.y,&n);
for(i=0;i<n;i++)
scanf("%d%d",&beeper[i].x,&beeper[i].y); memset(visit,0,sizeof(visit));
minimum=INT_MAX;
dfs(0);
printf("The shortest path has length %d\n",minimum); }
return 0;
}

2.2 POJ 1256

题目大意:有n个字母word,可能含有重复元素,求其全排列。

在DFS生成排列时,会碰到重复元素,为了不重复输出同一个排列,需要进行剪枝。扫描到当前字母i与其前一个字母i-1相同,且字母i-1未被访问,则选择跳过。

少写了一句结束标志 result[depth]='\0';   WA了N久。分析:因为result会记录上一个word的排列,所以会对下一个word产生影响;比如,输入abc和ab,等到输出ab的排列时,会输出cba的结果。

源代码:

1256 Accepted 156K 32MS C 825B 2013-10-11 15:27:01
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h" int n,visit[13];
char word[13],result[13]; int cmp(const void *a,const void *b)
{
char c=*(char *)a,d=*(char *)b;
return tolower(c)==tolower(d)?c-d:tolower(c)-tolower(d);
} void dfs(int depth)
{
int i;
if(depth==n)
{
result[depth]='\0'; //少写了这一句,WA了N久
puts(result);
return;
} for(i=0;i<n;i++)
{
if(i>0&&word[i]==word[i-1]&&!visit[i-1]) //剪枝:如果当前字母i与其前一个字母i-1相同,且字母i-1未被访问,则跳过
continue;
if(!visit[i])
{
visit[i]=1;
result[depth]=word[i];
dfs(depth+1);
visit[i]=0;
}
}
} int main()
{
int num_word;
scanf("%d",&num_word);
while(num_word--)
{
scanf("%s",word);
n=strlen(word);
qsort(word,n,sizeof(char),cmp);
memset(visit,0,sizeof(visit));
dfs(0);
}
return 0;
}

【算法】深度优先搜索(DFS)III的更多相关文章

  1. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...

  2. 深度优先搜索 DFS 学习笔记

    深度优先搜索 学习笔记 引入 深度优先搜索 DFS 是图论中最基础,最重要的算法之一.DFS 是一种盲目搜寻法,也就是在每个点 \(u\) 上,任选一条边 DFS,直到回溯到 \(u\) 时才选择别的 ...

  3. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  4. 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)

    需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...

  5. 深度优先搜索DFS和广度优先搜索BFS简单解析

    转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...

  6. 算法与数据结构基础 - 深度优先搜索(DFS)

    DFS基础 深度优先搜索(Depth First Search)是一种搜索思路,相比广度优先搜索(BFS),DFS对每一个分枝路径深入到不能再深入为止,其应用于树/图的遍历.嵌套关系处理.回溯等,可以 ...

  7. 图的深度优先搜索(DFS)和广度优先搜索(BFS)算法

    深度优先(DFS) 深度优先遍历,从初始访问结点出发,我们知道初始访问结点可能有多个邻接结点,深度优先遍历的策略就是首先访问第一个邻接结点,然后再以这个被访问的邻接结点作为初始结点,访问它的第一个邻接 ...

  8. 算法总结—深度优先搜索DFS

    深度优先搜索(DFS) 往往利用递归函数实现(隐式地使用栈). 深度优先从最开始的状态出发,遍历所有可以到达的状态.由此可以对所有的状态进行操作,或列举出所有的状态. 1.poj2386 Lake C ...

  9. 深度优先搜索(DFS)

    [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ...

  10. HDU(搜索专题) 1000 N皇后问题(深度优先搜索DFS)解题报告

    前几天一直在忙一些事情,所以一直没来得及开始这个搜索专题的训练,今天做了下这个专题的第一题,皇后问题在我没有开始接受Axie的算法低强度训练前,就早有耳闻了,但一直不知道是什么类型的题目,今天一看,原 ...

随机推荐

  1. u-boot 2016.05 添加自己的board 以及config.h

    拿到一个uboot 后,我都想添加一个属于自己的board文件以及include/configs/*.h 文件. 如何添加这个些文件,今天来记录一下. 复制一份你所参考的板级文件,比如说board/v ...

  2. kubernetes外部访问的几种方式

    1:用的最多的是nodePort,如下nginx的service,将type设置成NodePort,同时nodePort设置成30010(k8s为了不与宿主机的端口冲突,默认限制了30000以下的端口 ...

  3. 訪问站点时仅仅是显示主页(index.jsp),没有请求连接数据库读取数据。

    两部曲: 1:在你的web.xml中的Struts2的核心过滤器的映射中添加 <filter-mapping>     <dispatcher>REQUEST</disp ...

  4. iOS边练边学--通讯录练习之Segue使用,控制器的数据传递

    一.什么是segue Storyboard上每一根用来界面跳转的线,都是一个UIStoryboardSegue对象(简称Segue) 二.Segue的属性 每一个segue对象,都有三个属性 < ...

  5. UML总结--总体架构

    架构图(一): 架构图(二): 转自:http://blog.csdn.net/lsh6688/article/details/5931706

  6. 《FPGA全程进阶---实战演练》第四章之Quartus II使用技巧

    技巧1:“新”技能 hierarchies警告寻找 在编译之后,警告中“hierarchies”这个单词大家估计都很熟悉了,一看到这个警告,基本上就是例化时出现的问题.一般例化时,要是哪个连线没引出, ...

  7. 【转】【Mysql】MySQL添加用户、删除用户与授权

    MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束): 1.新建用户 1.1 登录MYSQL: @>mysql -u root -p @&g ...

  8. C++ 有用的网站

    C++ 有用的网站C++ Programming Language Tutorials ? C++ 编程语言教程.C++ Programming ? 这本书涵盖了 C++ 语言编程.软件交互设计.C+ ...

  9. (转)windows平台时间函数性能比较QueryPerformanceCounter,GetTickCount,ftime,time,GetLocalTime,GetSystemTimeAsFileTime

    执行 10000000 次, 耗时 2258,369 微秒     QueryPerformanceCounter 执行 10000000 次, 耗时 26,347 微秒    GetTickCoun ...

  10. OpenGL介绍

    OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植:OpenGL可以与Visual C++紧密接口,便于实现机械手的有关计算和图 ...