【AcWing算法提高课】1.2.2最长上升子序列(二)

AcWing算法提高课 1.2.2最长上升子序列(二)
摘要由CSDN通过智能技术生成

在这里插入图片描述

零、回顾最长上升子序列的 O ( n log ⁡ n ) O(n\log n) O(nlogn) 做法

设当前最长上升子序列的长度为 l e n len len,额外数组 q [ i ] q[i] q[i] 记录当前所有长度为 i i i 的上升子序列的末尾元素的最小值。

从前往后对于每一个元素 a [ i ] a[i] a[i]

  1. a [ i ] > q [ l e n ] a[i] > q[len] a[i]>q[len],那么 a [ i ] a[i] a[i] 可以接在当前最长上升子序列的后面,更新当前最长上升子序列长度 ( l e n = l e n + 1 len=len+1 len=len+1),更新长度为 l e n + 1 len+1 len+1 的上升子序列的末尾元素的最小值 ( q [ l e n + 1 ] = a [ i ] q[len+1]=a[i] q[len+1]=a[i]);
  2. 否则,二分 (可以证明 q q q 数组中的元素一定单调增,这是降低时间复杂度的关键) 找到 q q q 数组中第一个大于等于 a [ i ] a[i] a[i] 的元素,用 a [ i ] a[i] a[i] 更新它。

一、拦截导弹

1010.拦截导弹 题目链接

第一问:求最长非上升子序列长度;
第二问:求最少用几个非上升子序列可以覆盖整个序列。

第二问分析:对于每一个导弹,有以下两种选择:

  1. 用现有的某套系统去拦截它,即把该元素接在某个非上升子序列的末尾;
  2. 新创建一个系统,即该元素作为新的非上升子序列的开头。

贪心流程:从前往后对于每一个导弹:

  1. 若现有的所有非上升子序列的末尾都小于这个数,则创建一个新的子序列;
  2. 否则找到末尾大于等于这个数且最小的非上升子序列,把这个数接到这个子序列的后面。

贪心证明:

  1. 证明两个数相等:设 A A A 表示贪心算法得到的序列个数, B B B 表示最优解,一定有 B ≤ A B\le A BA,因此只要证明 A ≤ B A\le B AB 即可。
  2. 调整法:假设最优解对应方案与当前方案不同,找到第一个不同的数。
    设当前的导弹为 x x x,当前所有的非上升子序列:
    _ _ _ _ _ _ _
    _ _ _ _ _ _ a a a
    _ _ _ _ _ _ _
    _ _ _ _ _ _ b b b
    其中贪心法方案是将 x x x 接在 a a a 的后面,最优解方案是将 x x x 接在 b b b 的后面。
    由贪心法流程可知 a ≤ b a\le b
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值