洛谷 P1020 [NOIP1999 提高组] 导弹拦截

原题链接 https://www.luogu.com.cn/problem/P1020

这个真的是一道好题,这道题不仅考察了dp,而且融合了二分还有一个很重要的Dilworth 定理

感觉做完这个题最大的收获不是dp,而是完善了二分的一些分支算法而且了解了上面说到的哪个定理

因为n ^ 2的dp谁都会,而优化就显得很重要了

在之前abc的比赛中我因为不会自己写二分而导致卡一道题卡了将近一个小时,那个题目考察到了求第一个大于(大于等于)aim的值和第一个小于(小于)aim的值,

在赛后我第一时间就完善了这两种算法,而在今天,我又遇到了求最后一个大于(大于等于)aim的值,和最后一个小于(小于等于)aim的值

其实想法都是差不多的,就是在二分时左右端点的转移条件不一样

在求第一个大于(大于等于)aim的值和第一个小于(小于)aim的值时,当A[mid]>aim时,我找到了一个大于aim的数字,因为数组是升序的,所以我在[l,mid - 1]继续寻找

(并将res赋值为mid(res初始为- 1))想要找到一个比aim大但是比A[mid]更小的数

如果A[mid]正好是第一个大于aim的数字,则意味着[l,mid - 1]中没有比aim更大的数字了,那么l会一直更新直到 l > r 循环结束

如果数组本身就没有大于aim的数字,l就会一直更新,直到 l > r,这个过程中res没有一次更新,res在循环结束后依然是-1

则res == -1 变成了一个判断找没找到的条件

其他同理

对于我今天遇到的问题,就是当A[mid]>aim时,我要在[mid + 1, r]中去找,想要找到一个大于aim并且比A[aim]更大的数,即向着最后一个大于aim的数字找去

后续细节和上面解释的一样

再就是Dilworth 定理:他的数学定义为对于一个偏序集,最少链划分等于最长反链长度

在这个求最长不升序列的背景下,Dilworth 定理可以解释为:一个序列的最少不升子序列划分块的数量,等于这个序列最长上升子序列的长度

注意:不升子序列对应<=,他的反链对应上升,即>,要清楚二分的时候求的东西

posted @ 2024-07-25 15:38  1DemonS2  阅读(26)  评论(0)    收藏  举报