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. 【C#】List<T>对象的深复制

    一.List对象中的T是值类型的情况(int 类型等) 对于值类型的List直接用以下方法就可以复制: List<T> oldList = new List<T>(); old ...

  2. [app]Linux的setitimer和sleep冲突

    在Linux中使用setitimer和sleep会冲突,二者都是用信号 碰上一个头疼的问题,主程序在sleep的时候,总是被开的一个timer的signal callback所影响, 每当timer的 ...

  3. JavaScrip——练习(做悬浮框进一步:悬浮窗后缀悬浮窗【感觉这种方法比较麻烦】)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. r函数知识总结

    1. rbind(), cbind():  构造.合并vector 或matrix为一个矩阵:cbind(1, 1:10) ----默认列合并, rbind(1, 1:10) ----行合并(or构造 ...

  5. 【转】WCF入门教程二[WCF应用的通信过程]

    一.概述 WCF能够建立一个跨平台的安全.可信赖.事务性的解决方案,是一个WebService,.Net Remoting,Enterprise Service,WSE,MSMQ的并集,有一副很经典的 ...

  6. C# 属性事件一些设置说明

    大致列举一些常用的属性或事件的一些修饰 用法类似,主要是对属性的进一步设置 [Browsable(true)] public bool Enable {get;set;} 顺便说一下事件的应用: pu ...

  7. C++ STL 教程

    C++ STL 教程在前面的章节中,我们已经学习了 C++ 模板的概念.C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的 ...

  8. sublime text 删除插件

    1.ctrl+shift+p 输入remove package 选择要删掉的插件即可 2.去掉产生临死文件的插件:phptools

  9. SharePoint 2010 自定义页面出现“项目可能已被其他用户删除或重命名”问题跟踪

    异常详细信息: Microsoft.SharePoint.SPException: 位置 http://portal/Pages/ShowArticle.aspx?id=19&mylist=8 ...

  10. mongodb group php 操作

    紧接着上篇来,这篇主要讲,mongodb的group功能,做的还是挺强大的,相当对于find(),skip(),distinct()等,用法比较复杂. 测试数据 > db.fruit.find( ...