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\) 时的状态转移图(矢量图,可以放大观看,箭头指向转移方格的右边框,如果搞不清了的话,鼠标放在线上会有提示):

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

最新文章

  1. Jquery元素选取、常用方法
  2. 作业七:团队项目——Alpha版本冲刺阶段005
  3. 基于AngularJS的过滤与排序
  4. ASp.net 注册
  5. c#获取系统时间的方法(转)
  6. [置顶] 小强的HTML5移动开发之路(9)——坦克大战游戏3
  7. C# 面向对象 , 类与对象
  8. pygame系列_箭刺Elephant游戏
  9. 创建你的第一个webdriver python代码
  10. python socket编程制作后门木马(原创)
  11. bzoj2005 NOI2010 方案统计
  12. 类String 常用方法
  13. docker 快速部署ES集群 spark集群
  14. idea properties文件中文无法正常显示
  15. 浅谈 drop、truncate和delete的区别
  16. SNF快速开发平台成长史V4.5-Spring.Net.Framework-SNF软件开发机器人
  17. VC.时间(网页内容收集)
  18. leetcode242—Valid Anagram
  19. php 时间操作归类
  20. 网易云安全DDoS高防全新上线 ,游戏防护实力领先

热门文章

  1. 利用函数计算构建微信小程序的Server端
  2. 容器HashSet原理(学习)
  3. ios22--动画
  4. ASP.NET调用存储过程并接收存储过程返回值
  5. JSSDK使用步骤
  6. gerrit+gitlab整合调试
  7. js moment.js日期操作类 datetime,日期操作,dayjs
  8. 【WIP】C基础语法
  9. bzoj 1677: [Usaco2005 Jan]Sumsets 求和【dp】
  10. bzoj 1668: [Usaco2006 Oct]Cow Pie Treasures 馅饼里的财富【记忆化搜索+剪枝】