算法竞赛进阶指南线性DP——最长上升公共子序列

在这里插入图片描述
前置知识
在这里插入图片描述

这里是最长上升子序列和最长公共子序列的结合。
我们在定义状态的时候,也可以将二者结合
先把公共子序列找出来,再找最大值
f(i,j)表示在a序列的1~i中和b序列的1 ~ j构成的以b[j]结尾的公共子序列长度的最大值
通常以最末态来做划分,最末态中,b[j]肯定在子序列中,而a[i]不一定,考虑是否可以以a[i]是否在LCIS序列中进行划分。(这里的划分方式同LCS)

lcs划分方式 👇
在这里插入图片描述
(1)当a[i]不在序列中,又因为b[j]一定在序列中,所以a[i]≠b[j],此情况下,等同于在a序列的前i-1的数中与b中的前j个数,且以b[j]结尾的LCIS ,即f(i-1,j)

(2)a[i]=b[j]时,为了使前面的数尽可能多的匹配,所以a[i]一定和b[j]配,找到了公共子序列,求最长,参考LIS的处理方式。

因为最后一位都是b[j],寻找倒数第二位,从0 ~ j-1 进行枚举→ k ,需要满足条件bk <bj

LIS的划分情况👇
在这里插入图片描述

在这里插入图片描述
综上,问题得以解决

转移
代码实现为:
在这里插入图片描述
这是O(n3

如何优化至O(n2)
一般情况下优化的方式是看某一维是否可以用其他维度表示出来。
我们发现j不同,k不用,探求一下j与k之间有什么样的关系吗?
j=1 k=0 b[k]<b[j]
j=2 k=0、1 b[k]<b[j]
j=3 k=0、1、2 b[k]<b[j]
即j每增加1,k中就会产生一个新的候选集合,但是因为必须要满足b[k]<b[j],如果b[j]非常小,候选集中的出入情况就会有变化。无法确定k与j之间的关系

但是我们发现,有k进行讨论的前提是a[i]==b[j],可以把条件转化为
b[k]<a[i] 这样a[i]在当前阶段中是一个定值,每次当j增大时,要么会有1个数进入候选集合中,要么没有。

举例
a[i]=5
b={0,2,4,6,2}
j=1 k=0
j=2 k=0,1
j=3 k=0,1,2
j=4 k=0,1,2(因为b[4]=6>a[i],不符合条件)
j=5 k=0,1,2,4
👉 发现每次最多有一个数进入候选集合中,且这个数是j-1
有了这个发现,则不用再遍历k了,每次只需要判断j-1是否要进入候选集合中即可。

即设s为候选集合,当j+1得到j+1时,此时的候选集合情况为:
如果b[j]>a[i] (此时a[i]==b[j+1]) 这个数不满足条件,无法进入候选集合中
如果b[j]<a[i]=b[j+1],j 进入候选结合中,当前的候选集为原来的s(i,j)并 {j}

在这里插入图片描述
代码实现👇
在这里插入图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
算法竞赛指南》是一本级别的书籍,不适合初学者阅读。根据引用中的描述,每一章都会总结书中的难点知识,并附上例题和习题。从引用的目录可以看出,《算法竞赛指南》包含了基本算法、位运算、递推与递归、前缀和与差分、二分、排序、倍增、贪心等内容,还包括了基本数据结构如栈、队列、链表、Hash、字符串、Trie、二叉堆等。此外,书中还讲解了动态规划的各种领域,如线性dp、背包、区间dp、树形dp、状态压缩dp等。对于想要深入学习算法竞赛的读者来说,《算法竞赛指南》是一本很好的参考书籍。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【算法竞赛指南】学习笔记](https://blog.csdn.net/cpp_juruo/article/details/122520206)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [算法竞赛指南总结(一)](https://blog.csdn.net/weixin_64393298/article/details/124234703)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值