观察题目可以发现这类似一个图论的问题,我们可以把可以到达的位置对建有向边,这显然是一个 DAG,所以直接跑拓扑排序最长路即可。
这样的复杂度是 O ( n 2 ) O(n^2) O(n2) 的,显然无法通过,而瓶颈在于建边部分。
考虑优化建边的复杂度。发现我们其实可以不用把这个格子 x x x 可以到达的格子全部连上,只需要连上最小的比它大的格子 y y y 即可,因为 y y y 一定可以到达更大的格子,也就优化了建边,这里可以使用 set 来记录那个格子。从此,建边的复杂度变成了 O ( n log n ) O(n \log n) O(nlogn)。
那么会有一个问题:如果碰到有很多个 y y y 怎么办?这个很简单,我们只需要向最长路最长的 y y y 连边即可,因为这样一定更优。
还会有一个问题:那么最长路怎么实时算出来?由最长路的值就可以想到可以无实物建图,那么此时 DAG 上的 DP 就变成了普通的 DP。我们设 d p i dp_i dpi 表示以 i i i 开始的路径的最长长度,为了保证无后效性,一开始要把所有格子的 a i a_i ai 从大到小排序,然后把 i i i 和 d p i dp_i dpi 的值压到 set 里面维护(注意要重载运算符),转移异常简单,每一次我们取出的 y y y,都有 d p i = max ( d p i , d p y + 1 ) dp_i=\max(dp_i,dp_y+1) dpi=max(dpi,dpy+1),这样就结束了。
另外还有一个小细节,就是我们在取 y y y 的时候,可能会取到和它相同的值(因为我们这里设最长路值更大的更优),这样我们判断一下就可以了。