舞蹈链 感悟

舞蹈链 感悟

        做了有一个星期的DLX专题了吧,感觉不写点东西就了点什么,为什么要做这个专题呢,感觉很多比赛都不会用到这个算法,比较冷门,但它毕竟在kuangbin的专题里排第三,那么肯定也就有学习的理由,并且本人对数据结构的掌握比较差,所以想学习一下这个十字交叉双向循环链表,训练一下自己对链表的能力和运用

        那么在说具体算法之前呢,先说一下自己的感想吧,在算法大纲里DLX是属于其他算法里,但也有很多人把他归纳到搜索的范畴里,可能他运用到了dfs和A*搜索吧,或者说十字交叉双向循环链表只是DLX所运用到的数据结构,具体的解决办法还是搜索,所以本人也把它放到了搜索的章节里,毕竟,数据结构只是解决问题的数学模型,具体还是要用算法来进行解决

        那么既然是归纳到了搜索的范围里,肯定避免不了剪枝的方法,如上面所说到的重复覆盖里的A强剪枝(其实本人在学DLX的时候并不会A),也算是学到了新东西吧,下面还会说一下自己的理解


        精确覆盖,选取最少(最多)的行的集合使得集合中每一列都恰好包含一个1,其实也没什么好说的,如果还没有学习过的人建议看一下这篇博客,讲的相当不错点我啊!!

        感觉很多时候它只会考你对模型的建立和简单的搜索剪枝,具体的改变十字交叉双向循环链表应该不怎么考,但是也要理解,不要死用模板,比如学会怎么在链表里永远除去一些列,比如POJ - 1084,单纯靠模板是走不了多远的!


        重复覆盖,选取最少(最多)的行的集合使得集合中每一列都包含一个或多个1,感觉如果是真的学会了精确覆盖的话,再去理解重复覆盖应该是顺水推舟,毕竟操作变得更简单了,唯一变化可能就是很多人的模板里给的A*强剪枝,一开始我看到这个剪枝的时候感觉比较熟悉,仔细一思考会发现:这不就是精确覆盖里删除列的操作吗??!

        学习还真的是触类旁通啊,在学习重复覆盖的过程中曾看到有人在博客里说道:重复覆盖里的A*强剪枝的思想,其实我们在其他搜索题里也会不自觉的用到,仔细一想,还是这么一回事


        说完这两个最简单的模板,在一起说一说我在学习和运用过程当中遇到的一些想法吧!
        ①:精确和重复的模板里都运用到了根据列结点数进行剪枝,很巧妙

        ②:重复的模板里的A*强剪枝其实是精确覆盖里删除列的操作,对可能最优情况和之前的结果进行判断

        ③:关于数组大小的问题,下面也还会说道,L[ ],R[ ],U[ ],D[ ]四个数组都是N*M + M的大小,因为还要加上每列的虚拟结点,同时注意X[ ],C[ ]行列编号也是这个大小,因为十字交叉双向循环链表,从某种意义上来说是以一维的形式来存储二维的图(不知道我这么说有没有认同),本人因为忘记改大小而de了几个小时才发现这个问题,当时很崩溃

        ④:如果题目已经给出固定的选出多少行来进行覆盖的话,无论是精确还是重复再dfs过程中都能进行剪枝,也就是对深度与题目所给出的大小进行比较,加速返回,比如很多DLX要用到二分的思想,几乎都要用到这个剪枝

        ⑤:最后,也是最重要的,模板是最简单的,一道好题如果考到了DLX的话,主要肯定是考你怎么去建立模型,或者看你能不能想到用DLX的覆盖思想来解决,如果不告诉你这道题是DLX套题里,你还能想到吗?(反正我是想不到)


        你以为我说完了吗?当然还没有,上面说完最基础的,再来简单说一下应用吧,比如网上给出的数独模板,其思想不过就是将更多的需要判断的条件转化为了更多的列而已,做的题一多你就会发现,DLX最精华的地方在于列与行之间的联系和列的增多方式,以此为基础可以扩展延伸到很大的范围~

        说到数独,这里给出讲的很好的博客链接吧,其实和上面那个讲解是同一个人:对,点我!

        无论是 9 × 9 数独 、16 × 16 数独,还是 M × M 数独(放心,最底下我会给模板的),其思想也都是一个道理,需要解决的不过都是列与行之间的建立,以及最后的答案解码过程(将一维数组答案解码成二维)

        当然kuangbin专题里还给出了变形数独,也就是锯齿数独!!,与普通数独唯一的区别只是宫的形状发生了变化而已,所以联想我们对普通数独的处理,我们只是需要知道宫的编号而已,所以对变形数独只需要加个BFS对宫进行编号即可,so easy!

        当然我做这题的时候还发现另外一个闪光点,题目用一个数字就存储了五个数据有木有!!同时存储了格子里的数值、格子是否处在上下左右边界这五个数据,这也变相告诉我们二进制真的是个很强大的东西~


        其实本来还想在这里总结一下DLX容易出错的几个点,但是感觉上面已经说的差不多了,而且每个人的习惯和代码风格都不一样,也就不在这里啰嗦了,然后,就到了大家最兴奋、最开心、最刺激的 给!模!板!环节啦!

        还是觉得模板这种东西吧,自己如果理解学会了的话自己打一遍还是要靠谱很多,网上传的那些乱七八糟的模板真的是很杂乱,而且和自己的代码风格很不一样,仔细斟酌吧!

舞蹈链 ——精确覆盖 模板
舞蹈链 ——重复覆盖 模板
舞蹈链 —— 9 × 9 数独模板
舞蹈链 —— 16 × 16 数独模板
舞蹈链 —— M × M 数独模板
舞蹈链 —— 锯齿数独参考
舞蹈链 —— 二分题型参考

不知觉就打了这么多,这破游戏本很长一段时间键盘不灵了,预计明年换台thinkpad吧


2020 / 6 / 7 补充:
删除列和恢复列的操作顺序是相反的,因为在dfs的过程中,要保证图不变
重复覆盖求最大值的A*搜索是错的,先已更新
我仍旧没有换电脑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值