一直对dfs这一块比较懵(其实递归也挺懵的),所以找机会总结一下dfs和一些能用到的模版,勿喷
什么是dfs呢?
DFS环球免税购,荟萃逾700个全球知名品牌,涵盖时装配饰,美妆香水,腕表珠宝,葡萄酒和烈酒,美食及礼品。官方正品保证,乐享免税价格。DFS旗下澳门T广场,限时美妆惊喜连连,更有电子消费卡等多重优惠奖赏。成为T贵宾,更可尊享DFS独家礼遇与会员积分!
咳咳,对不起,搞错了,再来。
深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.
举例说明之:下图是一个无向图,如果我们从A点发起深度优先搜索(以下的访问次序并不是唯一的,第二个点既可以是B也可以是C,D),则我们可能得到如下的一个访问过程:A->B->E(没有路了!回溯到A)->C->F->H->G->D(没有路,最终回溯到A,A也没有未访问的相邻节点,本次搜索结束).

(以上内容来源于百度百科)
算法这个东西知道是什么东西就行了,主要还是得由题说事,那么——
首先就是最经典的全排列问题:
1、全排列问题
【问题描述】 输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的 数字。 【输入格式】 n(1≤n≤9)
【输出格式】 由 1~n 组成的所有不重复的数字序列,每行一个序列。
可以发现,这就是一个典型的dfs,我们可以设置一个judge数组,用来记录当前的数有没有被取过,然后搜就完了,这个比较简单

#include<cstdio>
using namespace std;
int n,r,tot = 0;
int ans[1001] = { },judge[1001] = { };
void dfs(int x){if(x > n){for(int i = 1;i <= n; i++){printf("%5d" ,ans[i]);}printf("\n");return;}for(int i = 1;i <= n; i++){if(judge[i] == 0){judge[i] = 1;ans[x] = i;dfs(x + 1);judge[i] = 0;}}return;
}
int main()
{scanf("%d" ,&n);dfs(1);return 0;
}

还有一种版本的全排列(其实是组合的输出):
【问题描述】
排列与组合是常用的数学方法,其中组合就是从 n 个元素中抽出 r 个元素(不分顺序且 r<=n),我们 可以简单地将 n 个元素理解为自然数 1,2,…,n,从中任取 r 个数。

现要求你用递归的方法输出所有组合。

例如 n=5,r=3,所有组合为:

l 2 3 l 2 4 1 2 5 l 3 4 l 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5 【输入】

一行两个自然数 n、r(1<n<21,1<=r<=n)。 【输出】

所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所 有的组合也按字典顺序。
这个其实跟全排列是类似的,只需要把标准全排列的输出条件改一下就行了,也比较简单,这俩我刚开始学的时候是死记硬背然后硬套用的,多用用才慢慢知道是怎么回事

#include<cstdio>
using namespace std;
int n,r,tot = 0;
int ans[1001] = { },judge[1001] = { };
void dfs(int x){if(x > r){for(int i = 1;i <= r; i++){printf("%d" ,ans[i]);}printf("\n");tot++;return;}for(int i = 1;i <= n; i++){if(judge[i] == 0){judge[i] = 1;ans[x] = i;dfs(x + 1);judge[i] = 0;}}return;
}
int main()
{scanf("%d %d" ,&n,&r);dfs(1);printf("%d" ,tot);return 0;
}

还有一道很经典的题,就是”臭名远扬“的八皇后:
N 皇后问题(queen.cpp) 【问题描述】 在 N*N 的棋盘上放置 N 个皇后(n<=10)而彼此不受攻击(即在棋盘的任一行,任一列和任一对角线上 不能放置 2 个皇后),编程求解所有的摆放方法。
(其实把8改成n是更具有普遍性的)

#include<cstdio>
using namespace std;
int tot = 0,n;
int a[100] = { },b[100] = { },he[100] = { },cha[100] = { },ans[100] = { };//二维数组容易乱,一位数组清晰一些
void print(){for(int j = 1;j <= n; j++){printf("%d " ,ans[j]);}printf("\n");
}
void dfs(int now,int x){if(now > n){tot++;if(tot <= 3) print();return;}for(int j = 1;j <= n; j++){if(b[j] == 0 && he[x + j] == 0 && cha[x - j + n] == 0){  //标记前后左右对角线b[j] = 1;he[x + j] = 1;cha[x - j + n] = 1;ans[now] = j;dfs(now + 1,x + 1);b[j] = 0;he[x + j] = 0;cha[x - j + n] = 0;}}
}
int main()
{scanf("%d" ,&n);dfs(1,1);printf("%d" ,tot);return 0;
}

还有一道模版题就是迷宫
迷宫问题(migong) 【问题描述】

设有一个 N*N(2<=N<10)方格的迷宫,入口和出口分别在左上角和右上角。迷宫格子中 分别放 0 和 1,0 表示可通,1 表示不能,入口和出口处肯定是 0。迷宫走的规则如下所示: 即从某点开始,有八个方向可走,前进方格中数字为 0 时表示可通过,为 1 时表示不可通过, 要另找路径。找出所有从入口(左上角)到出口(右上角)的路径(不能重复),输出路径总 数,如果无法到达,则输出 0。
这个肯定还是dfs(其实bfs也是可以的)

#include<cstdio>
using namespace std;
int place[10001][10001] = { },judge[10001][10001] = { };
int n,tot = 0;
void dfs(int x,int y){if(judge[x][y] == 1 || x < 1 || y < 1 || x > n || y > n) return;if(x == 1 && y == n){tot++;return;}judge[x][y] = 1;dfs(x,y + 1);dfs(x + 1,y + 1);dfs(x + 1,y);dfs(x,y - 1);dfs(x - 1,y + 1);dfs(x + 1,y - 1);dfs(x - 1,y);dfs(x - 1,y - 1);judge[x][y] = 0;
}
int main()
{scanf("%d" ,&n);for(int i = 1;i <= n; i++){for(int j = 1;j <= n; j++){scanf("%d" ,&place[i][j]);judge[i][j] = place[i][j];}}dfs(1,1);printf("%d" ,tot);return 0;
}
/*30 0 00 1 11 0 0*/

那么有了这几道模版题,有很多类型题就可以迎刃而解了,
设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为c ij 。试设计一个算法,为每一个人都 分配一件不同的工作,并使总费用达到最小。 【编程任务】

设计一个算法,对于给定的工作费用,计算最佳工作分配方案,使总费用达到最小。 【输入格式】

第一行有1个正整数n (1≤n≤20)。接下来的n行,每行n个数,第i行表 示第i个人各项工作费用。
这道题其实就是一个八皇后,只不过把对角线的判定去掉就行了

#include<cstdio>
using namespace std;
int tot = 230081343,n;
int a[100] = { },b[100] = { },ans[100] = { },k = 0;
int h[10001][10001] = { };
void print(){k = 0;//≥ı ºªØ for(int i = 1;i <= n; i++){k = k + h[i][ans[i]];}if(k < tot) tot = k;
}
void dfs(int now,int x){if(now > n){print();return;}for(int j = 1;j <= n; j++){if(b[j] == 0){b[j] = 1;ans[now] = j;dfs(now + 1,x + 1);b[j] = 0;}}
}
int main()
{scanf("%d" ,&n);for(int i = 1;i <= n; i++){for(int j = 1;j <= n; j++){scanf("%d" ,&h[i][j]);}}dfs(1,1);printf("%d" ,tot);return 0;
}
/*34 2 52 3 63 4 5*/

而排列组合可以用来解决子集合问题等,其实用dfs解决这些问题归根结底就是暴搜,所以应该特别关注一下数据范围,然后想尽一切办法减少搜索次数,不然的话非常容易爆时间,严重的时候一半多的数据都过不去
我的dfs总结更新啦!以下是新的内容

海战
在峰会期间,武装部队得处于高度戒备。警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机。此外,巡洋船只和舰队将被派去保护海岸线。不幸的是因为种种原因,国防海军部仅有很少的几位军官能指挥大型海战。因此,他们考虑培养一些新的海军指挥官,他们选择了“海战”游戏来帮助学习。

在这个著名的游戏中,在一个方形的盘上放置了固定数量和形状的船只,每只船却不能碰到其它的船。在这个题中,我们仅考虑船是方形的,所有的船只都是由图形组成的方形。编写程序求出该棋盘上放置的船只的总数。

输入格式

输入文件头一行由用空格隔开的两个整数R和C组成,1<=R,C<=1000,这两个数分别表示游戏棋盘的行数和列数。接下来的R行每行包含C个字符,每个字符可以为“#”,也可为“.”,“#”表示船只的一部分,“.”表示水。

#include<cstdio>
#include<iostream>
using namespace std;
char s[10001][10001];
bool jd[10001][10001];
int r,c;
int tot = 0;
void dfs(int x,int y){if(jd[x][y] != 0 || x > r || y > c || x == 0 || y == 0 || s[x][y] != '#'){return;}if(jd[x][y] == 0 && s[x][y] == '#'){jd[x][y] = 1;dfs(x + 1,y);dfs(x - 1,y);dfs(x,y + 1);dfs(x,y - 1);}return;
}
int main(){scanf("%d %d" ,&r,&c);for(int i = 1;i <= r; i++){for(int j = 1;j <= c; j++){cin>>s[i][j];}}
//    for(int i = 1;i <= r; i++){//      for(int j = 1;j <= c; j++){//            printf("%c" ,s[i][j]);
//        }
//        printf("\n");
//    }for(int i = 1;i <= r; i++){for(int j = 1;j <= c; j++){int k = 0;if(s[i][j] == '#')k++;if(s[i + 1][j] == '#')k++;if(s[i][j + 1] == '#')k++;if(s[i + 1][j + 1] == '#')k++;if(k == 3){printf("Bad placement.");return 0;}}}for(int i = 1;i <= r; i++){for(int j = 1;j <= c; j++){if(s[i][j] == '#' && jd[i][j] == 0){//                printf("%d %d\n",i,j);dfs(i,j);tot++;}}}printf("There are %d ships." ,tot);return 0;
}

这道题的dfs思路不同于以往,这道题是要依靠dfs把一条船清空,我们先判断它是否是不合理的摆放,如果不是的话从头开始枚举点dfs,当我们找到代表船的点,进入dfs,把这一整条船都清空,这样一来dfs的次数就是船的数量了

下面是一道类似的题:细胞数量
一矩形阵列由数字 0 到 9 组成,数字 1 到 9 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。
这道题还是跟刚才一样了,用dfs清空细胞,dfs的次数就是细胞数

#include<cstdio>
#include<cstring>
using namespace std;
int m,n;
int a[10001][10001] = { };
int dx[] = {1,0,-1,0},dy[] = {0,1,0,-1};
void dfs(int x,int y){if(x > n || y > m || x < 1 || y < 1 || a[x][y] == 0){return;}a[x][y] = 0;for(int i = 0;i < 4; i++){dfs(x + dx[i],y + dy[i]);dfs(x + dx[i],y + dy[i]);dfs(x + dx[i],y + dy[i]);dfs(x + dx[i],y + dy[i]);}
}
int main(){scanf("%d %d" ,&n,&m);for(int i = 1;i <= n; i++){for(int j = 1;j <= m; j++){scanf("%1d" ,&a[i][j]);}}int tot = 0;for(int i = 1;i <= n; i++){for(int j = 1;j <= m; j++){if(a[i][j] != 0){tot++;dfs(i,j);}}}printf("%d" ,tot);return 0;
}

由这两道题可见,dfs还是可以用的非常灵活的,我对dfs的理解和应用肯定也不是那么的厉害,所以还是需要继续通过刷题来提高啊QAQ

老头怎么打边惩程咬金?相关推荐

  1. 健身环爆打老头环!超高难度击败boss,宫崎英高估计也想不到,代码+硬件教程已开源...

    晓查 萧箫 发自 凹非寺 量子位 | 公众号 QbitAI 7天销量破1000万的<艾尔登法环>,彻底火出圈了. 被玩家们亲切称为"老头环"的它,首发当日在线人数就在S ...

  2. 街头抓拍之一:酷似福克纳的老头

    灯市口.一个酷似威廉·福克纳的老头,在街口专注地等着人行道的绿灯. 东华门小吃街.一个睡态可掬的小男孩. 故宫前广场.两个公然掰腕较力的汉子.

  3. 最优化课程笔记07——约束问题的非线性规划方法(重点:拉格朗日乘子法和惩罚函数法)

    7.1 间接法:约束转化为无约束问题(含一个重点:拉格朗日乘子法) 当维数多的时候不适用 7.1.2拉格朗日乘子法(重点) 7.1.2.1 等式约束问题 7.1.2.2 不等式约束问题 7.1.3 惩 ...

  4. matlab 约束函数,【优化求解】MATLAB约束优化之惩罚函数法

    一.算法原理 之前我们了解过的算法大部分都是无约束优化问题,其算法有:黄金分割法,牛顿法,拟牛顿法,共轭梯度法,单纯性法等.但在实际工程问题中,大多数优化问题都属于有约束优化问题.惩罚函数法就可以将约 ...

  5. 王者荣耀 兵线刷新时间计数器 || 程咬金 水晶断兵线时间

    软件在百度网盘,链接:https://pan.baidu.com/s/1sp3_8JawMIU8DDX-npuVEw 密码:yhpw 这是一个用C#写的,在电脑上运行de小软件.       在看熊猫 ...

  6. 养狗养成小老头?宠物泪痕严重如何护理?

    宠物泪痕护理 宠物泪痕的问题肯定大家都不陌生 两条黑红丑丑的痕迹像是两撇胡子 让原本可爱的毛孩子像一个邋遢的小老头 今天胖胖和大家分享 宠物泪痕护理! NO.1 宠物泪痕严重的原因 一.饮食不当: 这 ...

  7. 抖音一个老人和一个机器人歌曲_《抖音》多年以后有个可爱老头歌曲分享

    小编最近在<抖音>里面听到了一首非常好听的歌曲,只不过歌名已经忘记了.而其中有一句歌词是:"多年以后有个可爱老头".不知道大家对于这一首歌有没有印象呢?接下来,小编就给 ...

  8. 《老头滚动条5》买屋 周详方案向导

    <老头滚动条5>买屋 周详方案向导 1·地点[雪漫城Whiterun-风宅Breezehome]·购屋:5000·装饰费用:1800 2·地点[马卡斯城Markath-林德尔会堂Vlind ...

  9. 王海桑《爷爷是个老头》

    爷爷是个老头 王海桑 打我记事开始,爷爷就是个老头 他那么老,好像从来不曾年轻过 他那么老,好像生来只为了做我的爷爷 可我从未认真想过他有一天会死 我总以为,一个人再老,总可以再活一年吧 然而有一天他 ...

最新文章

  1. 2020人工智能课程超级大列表:深度学习-强化学习-图神经网络-自然语言处理等...
  2. Xamarin.Forms单元控件Cell
  3. python调用r语言_【Python调用第三方R包】【环境变量设置】Python 通过rpy2调用 R语言...
  4. 工作195:解决key值不唯一的报错
  5. 手机modem 开发(2)---MTK modem的修改点
  6. bzu-java(五)
  7. Visual Studio 2015 前端开发工作流
  8. ETC passwd 用户和组管理
  9. Jira7.10.1在Windows环境下的安装和配置
  10. 企业分布式微服务云SpringCloud SpringBoot mybatis (八)消息总线(Spring Cloud Bus)
  11. 管道无损检测python_初用python-docx
  12. kubelet liveness probe源码简析
  13. 2018金山wps暑期招聘服务器端笔试题(第二批)
  14. 用UWP模仿网易云音乐的动画
  15. 大三Web课程设计——悬崖上的波妞(4页) HTML+CSS(可以很好的应付老师的作业)
  16. 解决摄像机被遮挡问题
  17. TeaTalk·Online 大数据+云原生,再度风云起
  18. Pandas中melt()的使用
  19. 4 NLP之数据平滑技术
  20. centos7无法读取移动硬盘

热门文章

  1. 电脑计算机u盘打印机,手把手处理win10系统设备和打印机选项无法打开的方案
  2. 自定义echarts地图展示行政区域
  3. python错误之db type could not be determined
  4. Flink程序启动报错could not be determined automatically
  5. 模仿扇贝短文阅读页面
  6. 文件默认保存位置无法使用 将不能正常使用微信,如何解决?
  7. Opencv 读取灰度图像会识别为3通道问题
  8. Python运用线程池ThreadPoolExecutor多线程下载搜索图片
  9. JAVA网络传输乱码问题
  10. IOS11 弹窗上文本框光标错位问题