点击查看微信稿件原文

点击上方蓝字关注
     #Paper     
Ingress Beijing


做为一名好久没开游戏,偶尔看看群,看看微信的老咸鱼,今天看到了群里有人在问北京启蒙军公众号上的《动态规划解两点多重问题》(下简称《问题》)一文里面的算法有没有实现好的轮子,作为一名好久没写程序的老咸鱼,也难免兴奋地搓手,有些跃跃欲试。但是,为啥记忆化搜索就写的这么简洁,而直接递推却要搞这么复杂呢?如果你急着出去抢 AP 不想看后文,那么这里是概括: field 之间的包含关系是一个偏序关系,所以问题本质是在有向无环图(偏序关系)上的动态规划。《问题》 中按照点到底边的距离排序,本质上是找出了一种此问题下有向无环图的拓扑序。


问题重述: 平面上有点 和  称为底边。又有点集 , 其中的点两两不重合(  ).


求一个最大的  使得  都有线段   分别不与线段相交。




很容易看出, 对于一个 ,, 要么 在 里面, 要么 在 外面. 如果我们将 定义为其覆盖的区域的点集,

那么我们可以将问题用包含于( )重述为

 (1)

注意, 包含于()的等号成立时当且仅当.


那么, 当两个点不相同时 () 这种包含关系一定是真包含 ().


我们可以发现,三角形的包含关系是一个偏序关系。下面讨论一下在 上的相对应的偏序关系.


定义


 

为 上的二元关系。那么,是:

自反的:

反对称的: 

传递的: 


因此,  是 上的偏序关系. 下面将 简记为 .




现在我们可以将 (1) 式用偏序关系 重新描述如下:


那么可以看出来,  是 的一条链 (chain). 也是全序的. 所以, 问题就转换成了求一个偏序集上的最长链. 


令 为 中, 以 为结尾的最长链 (即 的满足全序性质的子集, 且 是其中的最大元) 的最大长度. 


 (*)

那么

 

就是《问题》文中的状态转移方程.

 

可以看出, 这是一个经典的动态规划问题. 动态规划问题的求解顺序非常关键, 这个问题通常使用记忆化搜索, 或者按照 DAG 图的拓扑序 (对应于偏序关系的线性扩展) 来递推. 很容易证明, 将  中的点, 按照到底边的距离升序排序, 是一个合法的线性扩展 (拓扑序), 这也是《问题》文中方法的正确性的关键.




记 为 到底边 的距离, 那么

 (2)


为了证明此命题, 我们证明


为假命题 (这是由于  ). 证明如下:


显然只需证当时,  . 容易知道

 可以有许多种取法, 比如, 分别由 和 向 作垂线 和 , 那么两条垂线要么在一条直线上,要么平行. 当他们在一条直线上时, 可以在上取得. 当他们平行时, 过 做 的平行线交 . 那么, 可以在 上取得.


所以 


因此, (2) 为真. 


现在, 我们根据 来定义一个二元关系:

 

简记为 . 那么根据(*), 可以知道

 


又因为 是从 到 的映射, 所以 是一个全序关系. 因此, 也是 的一个线性扩展 (linear extension). 所以, 使用  来做为动态规划的顺序是正确的. 




由于我几乎所有名字里面带有“数”的课程都是 60 多分飘过, 或者重修过, 所以可能这些本来很简单的东西我却说得非常啰嗦, 或者蕴含了许多 bug, 所以欢迎评论指出错误. 另外, 欢迎在评论区提出新的改进,比如新的线性扩展方法, 或者更简洁的  的取法.



It's Time to Move! 

点击阅读全文

欢迎登陆北京ingress蓝军官网


扫一扫关注我们吧↓

转载我们文章的声明

本文还将被推送到

读读日报RSS

Telegram,Twitter

历史文章请访问 https://bjres.net  查看

投稿邮箱:tougao@bjres.net

如投稿后未得到回复,请Tele联系 @alexrowe


戳原文,更有料!