码迷,mamicode.com
首页 > 其他好文 > 详细

kuangbin专题二(搜索进阶)题解与反思

时间:2020-09-12 21:37:17      阅读:31      评论:0      收藏:0      [点我收藏+]

标签:变形   压缩   形式   计算   dbf   长度   意义   需要   复杂   

八数码问题

逆序对个数变化问题

首先复习一下逆序对,在一个序列中,如果下标\(i<j\)并且\(A[i]>A[j]\)则称ij为一对逆序对,可以看到逆序对最多为\(n*(n-1)/2\),这种成对的关系中。

如果将八数码看做是一条字符串的话,那么每一次移动必然会使得逆序对个数的奇偶性发生改变。这一原理是极易证明的。
下证明一个推广形式。

对于一串字符串,任意交换其中两个不相等元素,必然使得逆序对个数奇偶性发生改变。

假设两个元素下标为i,j则两个元素之间的元素个数则为j-i-1,则两个元素之间由于交换位置导致逆序对个数发生奇数次变化(1,-1),
而他们之间的每个元素和这两个元素之间的关系都会发生逆转,所以导致逆序对个数发生偶数次变化,综上,每交换字符串两个不相等元素都会使逆序对个数的奇偶性发生逆转。

所以就八数码问题而言,如果将那!八!个数码按照顺序编成字符串,那么那个空格左右移动的时候,并不会改变这字符串,如果是向上或者向下移动的时候,可以将其看做是连续向左或者向右移动两次达到。例如:

1 2 3

4 5 6

7 8 X

转变成

1 2 3

4 5 X

7 8 6

序列分别为:12345678 12345786 可以看到,6可以理解为向右移动了两次,而且这个移动的次数就是矩阵的宽度-1.而八数码问题中矩阵宽度为3,所以向上下移动的时候,并不会改变逆序对奇偶性,如果矩阵宽度为4则没有这样的结论了。

综上所述,由于八数码问题中矩阵宽度为3,导致上下移动的时候不改变逆序对奇偶性,左右移动本身就不改变字符串序列,所以在整个移动过程中,其奇偶性保持不变,因而我们可以确证,八数码问题起始奇偶性和目标奇偶性不相同,则必然无解。因此,我们可以直接地判断出那无解的情况。

但是对于那起始和目标奇偶性相同的情况,是否一定有解则未可知了。网上说来是有解的。

据此有一系列可以推广的方向,但是证明暂且未知。首先就是有解无解的判定,如上所述。还有就是对于\(N*N*N\)三维的形式,也有类似的规律,因为对于N为奇数,N-1 和N*N -1都为偶数。

康托展开

首先必须要记住的是,康托展开的本质是计算给定排列在所有全排列当中的字典序的位置次序。

所以这建立起来的是一一对应的关系,所以是一种极为高效的压缩状态的方法。由于这种双射关系,因而康拓展开是可逆的。

对于任意一个全排列,如果要求其位置,则只需要求出有多少个排列小于他即可,例如 21354,第一位,小于2的有1,所以有\(1*4!\)种排列小于当前排列。如果第一位固定为2,则检查第二位,发现没有小于第二位的,所以在第二位上小于当前排列的有\(0*3!\)。第二位固定为1,再看第三位为3,小于第三位的有12,但是12都已经被列举出来了,所以当前位也是0,再看第四位,小于5的有1234,被列举的除去之后,只有4,所以\(1*1!\)的。

因而可以总结康托展开过程为,对于长度为n的全排列,当前位为第i位(1~n),则当前位的权重为(n-i)!系数为,小于当前值的个数减去被枚举过的数小于当前值的个数。这个个数可以用树状数组解决。树状数组定义为前n个数字中未被枚举过的个数。那么初始化的时候,都没有被枚举,每枚举一位,则将对应区间减去1 即可。

对于逆康托展开,由于我们已经知道了康托展开公式就是\(a_1*(n-1)!+a_2*(n-2)!+...a_n-1*1!\),那么我们除以(n-1)!并向下取整,就可以得到\(a_1\)的值了,那么如何求出原来的值呢?可以用树状数组维护区间上未被枚举过的数量,那么当未被枚举过的数量为\(a_1\)时候,这个值就是我所要求的值。这个可以用二分查找。

康托展开如果想要方便的话,就要用1~N作为全排列的元素

关于八数码的变形

不得不说,八数码果然nb!就Eight II这题,就很巧妙。这一题要求出一个八数码到另一个八数码的最短字典序最小的路,这题我一开始的想法就是简单的BFS,然后TLE,因为有200组数据,最坏的情况是一次跑十几万,差不多是不可的。然后就想到用双向BFS,这个方法确实能够大大地降低复杂度的,但是不知道为什么老是过不了。

然鹅,我们在这个过程中曾经闪过一个念头却没有仔细想下去。普通的八数码,是一个起始状态然后BFS直接把所有其他状态都推出来了,然后打表就可。这一题我也想过是不是可以将所有情况全部遍历过,然后查表就可。然鹅这起始状态和中止状态各不相同,我就放弃了这种想法。

实际上我们没有想到的是,八数码问题的本质是什么?换句话说,我们能不能把八数码问题进一步抽象地表达呢?我们注意到,八数码问题本质是九个元素当中指定的一个元素和周围换位置。所以九个元素中能指定的分成九种,因而实际上八数码问题只有九种初始状态。而那八个数码的具体值则是表象,是对那个数码的一种具体化表示,或者说是一种命名罢了。所以我们应该还原其本质,将命名换掉,换成适合于语言表达的形式。

这让我想到了命名。或者说是语言,所谓语言是存在的家,在这里看来,我们描述问题,实际上是在描述事物的存在方式,表述事物内部和事物之间的联系。具体的一个事物可以被抽象为一个点,是那关系定义出了事物的意义。所以我们对事物的描述就是对关系的表述。将关系理清楚,我们就能使得事物向着我们希望的方向走。

Nightmare Ⅱ

这题非常重要,就在于曼哈顿距离。这个东西我们太过忽视了。原因就在于我们搜寻最短路的时候一般都是有障碍物的,因而从一个点出发到另一个点不得不进行搜索。但是,如果没有任何障碍物的话,那么直接用曼哈顿距离就可以求出那最短路,或者说在规定时间内能够到达的最大距离了。

这一题当中的鬼就是独特的存在,他可以穿墙而过,意味着整幅地图是没有鬼到不了的地方,那么鬼到达每个点的时间可以用曼哈顿距离求解了。所以是否遇到鬼只是一个判断条件罢了。而男孩女孩的又有些新的变化,男孩可以走三步,而女孩走一步。这里显而易见的是双向BFS,我们应该要学会在恰当的时候用DBFS

travelling

这题最重要的是用三进制,这题中每个点可以遍历至多两次,我就想着用两个二进制bit位来表示,但是这会造成巨大的浪费,状态很不密集,导致的后果就是,这一题如果用二进制,一共有\(2^{20}=100万\)而实际上用三进制则是\(3^{10}=6万\) 这个差距是惊人的。

我们之所以排斥用三进制,是由于其看起来麻烦,但是如果用digit[i][j]来表示十进制i的每一位上面的数码,我们将会发现其实是非常方便的。我们可以直接地知道一个状态的某个位上的值,并且这占用的空间也会很小。

kuangbin专题二(搜索进阶)题解与反思

标签:变形   压缩   形式   计算   dbf   长度   意义   需要   复杂   

原文地址:https://www.cnblogs.com/wbhqwq/p/13591319.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!