RQNOJ #204 特种部队 sol

link

首先我们可以注意到一个非常无聊的性质。先一直向右边走,然后折返回来向左边走,本质上与先向右走,然后向左走,再向右走这样循环走完整个路程是一致的。

根据这个性质,我们可以将向左走与向右走两个东西放在一起进行 DP。考虑状态 \(f[i][j]\) 表示最后一步向右走到 \(i\) 最后一步向左走到 \(j\)。我们考虑什么状态可以更新到当前状态。

我们容易发现,我们在 DP 的过程中实际上每次枚举 \(i\) 时,都保证了 \(i\) 之前的所有状态都更新了。即我们可以保证,\(i\) 之前的点都已经经过了。我们只需要考虑当前这一步如何走。

那么很简单的转移。考虑我们本质上是要找两条不相交的路径覆盖直线上的每个点。所以我们就可以硬淦出一个状态转移方程(大分类讨论)。

我们设 \(k=\max(i,\,j)+1\),则我们下一步就是要转移到这个位置(走到下一个点)。我们不需要讨论当前这一步是需要向左走还是向右走,在状态转移 \(i\) 变化的过程中,会自动的完成向左走和向右走的改变。我们只需要考虑向右走的情况就可以了,即状态的转移基于走一步而不是走的方向。

那么我们容易得到:

\[\begin{cases} f[i][k]=\min(f[i][k],f[i][j]+dis[j][k])\\ f[k][j]=\min(f[k][j],f[i][j]+dis[k][i])\\ \end{cases} \]

为什么这样转移没问题呢?注意到我们转移的时候,实际上是分了两种情况进行转移,即我们让 \(i\) 在这一步中跳到了 \(k\)\(j\) 不变与让 \(j\) 在这一步中跳到了 \(k\)\(i\) 不变。这样实际上就对应于讨论了每一种跳法。每一次只能向前多跳一步。

状态转移图的话,可以随便用 GraphViz 画一个出来,下面这张图为 \(n=5\) 时的状态转移图(矢量图,可以放大观看,箭头指向转移方格的右边框,如果搞不清了的话,鼠标放在线上会有提示):

嗯,有点乱,但是仔细观察我们还是可以发现其中的一些规律的。每个状态都转移到了两个点上。不难发现转移到的两个点对应的正好是对应向左和向右跳的位置。所以这从另一个方面印证了我们的状态转移没有问题。

posted @ 2018-09-05 17:49  baka  阅读(120)  评论(0编辑  收藏  举报