UVa 1471 Defense Lines (解释紫书思路)

题目链接:https://cn.vjudge.net/problem/UVA-1471

这里写图片描述

设序列L表示连续递增子序列
则最长的L就可以分为两部分,一部分是以j结尾的序列,另一部分是以i为开头的序列
现在我们来设置f(i)表示以i为开头的最长L的长度,g(i)表示以i为结尾的最长L的长度。这样一来我们可以在O(n)的时间复杂度内求出所有的f(i)和g(i),则最长序列L的长度就是g(j) + f(i)

现在我们枚举每个 i,同时从位于i的前面取出一个 j,这个 j 满足 j < i,同时 j 对应的元素即 A[j] < A[i],否则无法拼起来。并且 g(j) 得是前面所有的 j 中 g(j) 最大的。现在我们考虑这么个问题,如果 A[j] <= A[j’] 且 g(j) > g(j’) 我们是不是可以删去 j’ 这个元素呢,基于这个思想,我们可以将 i 前面所有的 j 处理成,若 A[j] > A[j’] ,则 g(j) > g(j’),这样的情况,这样一来我们就只需要寻找 i 前面的,满足 j < i,且A[j] < A[i],并且A[j]要尽量的大,这样一来我们就可以优化了。

维护一堆二元组 (A[j], g[j]) ,对于两个二元组,若 A[j] > A[j’] ,则 g(j) > g(j’),这样一来我们就可以,对其按照 A[j] 排序,这样一来我们,在枚举 i 的时候直接二分查找适合的 j 即可,但是还有个问题,我们每次计算完一个 i 之后,都得将 i 加入这一堆二元组中,供下一个 i 使用,这样一来我们就需要插入,什么时候使

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值