题目大意:
有n个矩形,每个矩形按从大到小排列,每个矩形的格子数目分别为n*n,(n-1)*(n-1)……(1*1),每个格子上都有一个数。表示走到这个格子所有耗费的时间,每次只能往上不能往下走(可以往四周走,矩形是大在下面)除了这些格子,现在还给出一些暗道,可以使得某个格子直接通到另一个格子(同样也是只能往上走,不能往下走),问你从最下面的矩阵的第一行第一格走到最顶一格所需花费的最短时间是多少?
这一题,我不得不吐槽。
不得不吐槽、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
进入正轨:
很明显,这道题一看就知道用搜索,纯DP是不可能的,因为题目不符合无后效性,所以,我就考虑搜索。
我一开始的方法就是DFS+记忆化,超时70...
仔细一想,dfs确实有些不妥,即使加了一大堆剪枝还是超(为什么不妥我就不解释了,233)
我马上把dfs改成了bfs(代码类似spfa核心代码,本蒟蒻就是从那儿得到灵感,实际上喝杯水醒醒大脑才觉得那应该叫记忆化。。。)
一改,觉得肯定AC了,谁知突然蹦出一个超时%90.
smg?
好吧,我承认我看着自己的代码看了3个小时,睡觉想了两个小时,硬是没任何进展。好咯,唯一的方法,打表,233...
好吧,当我打了表之后,我看了看众多神犇的方法,奇怪,与我的方法一模一样啊,真的一模一样啊,怎么会错呢?于是乎,我几乎把代码改了一半了,还是超时,这什么鬼啊 。。。。。。。。。。
最后,在刚刚过去的20分钟里,我突然发现了一个重大的问题,我是用集合判断边界,也就是判断x,y是否在[1..n]里。。。。。。。。。。。。。。。。。。。。。。。。。。
这就是著名的卡常数。。。。
我(ri)很(ni)伤(da)心(ye)
好吧,我改了判断边界之后就妥妥的AC了。。
进入优化阶段:
我这里的bfs是最暴力的一种,一直往外拓展可能拓展的节点,直道拓展不了为止,但这样子做如果数据再极端一点的话,有可能导致你当前从一个原始节点拓展一个节点x,反而这个节点x一直往外拓展的时候最后还有可能把原始节点给更新了,这种情况如果重复出现的话,队列就要开到很大,即使用循环队列也得担心时间的问题。
所以我们可以想想优化,首先,第一层很明显不可能由第零层得来,也不可能由暗道得来,所以我们只需对第一层往四周拓展的bfs即可。
于是乎,对于第二层的每个节点,我们很明显可以选一个从第一层拓展到这个节点的最短路径,这里非常需要注意的是不需要第一层的每个节点都来更新第二层的节点,不然会答案错误,我们只需选择第一层能直接到达第二层某个节点的节点来更新第二层的某个节点(好好理解这句话。。。。233)
做完这个类似DP的步骤时,我们则可以看看这些节点是否能由暗道通往,如果有暗道通往的话又把他更新一次,这样更新完之后,我们可以得到一个可观的答案,我们再对这些答案进行类似第一层的操作,则可以得到正确答案了,很明显,这种方法的正确性是很容易得到类似证明的证明。
时间复杂度接近0.1s
好咯,吐槽完毕,说说总结:
前几次有一次做题目就被集合的最大范围[0..255]给坑了,今日再次被这脑残的判断方法的脑残效率给坑了,我已决定,今后不管还剩多少时间,我都不投篮地写个判断集合了,一定写if语句,233...