最长公共上升子序列(LCIS)

from math import inf
# 最长公共上升子序列
# a,b是长分别为m,n的两个数组,找出a,b中公共上升子序列的长度
# dp定义:f[i][j]为a的前i个数、b的前j个数中以b[j]结尾的(可以包含a[j],也可以不包含)最长上升子序列的长度
# 最终答案为max(f[m][j] for j in range(1,n+ 1))
# 朴素解法O(n3)
a = [-inf] + list(map(int,input().split()))
b = [-inf] + list(map(int,input().split()))
m,n = len(a) - 1,len(b) - 1
f = [[0]*(n + 1) for _ in range(m + 1)]
for i in range(1,m + 1):
    for j in range(1,n + 1):
        # 如果不选a[i]
        f[i][j] = f[i - 1][j]
        # 如果选a[i],那么a[i] == b[j]
        if a[i] == b[j]:
            # 转移到b[k],要求b[k] < b[j]
            for k in range(j): # 注意k从0开始
                if b[k] < b[j]:
                    f[i][j] = max(f[i][j],1 + f[i - 1][k])
print(max(f[m][j] for j in range(1,n + 1)))

# 优化版本O(n2)
# f[i][j] 只和f[i-1]有关
a = [-inf] + list(map(int,input().split()))
b = [-inf] + list(map(int,input().split()))
m,n = len(a) - 1,len(b) - 1
f = [[0]*(n + 1) for _ in range(m + 1)]
for i in range(1,m + 1):
    maxv = 0
    for j in range(1,n + 1):
        # 如果不选a[i]
        f[i][j] = f[i - 1][j]
        # 如果选a[i],那么a[i] == b[j]
        if a[i] == b[j]:
            f[i][j] = max(f[i][j],1 + maxv)
        if a[i] > b[j]: # a[i]可以作为b[j]之后的b[k]匹配
            maxv = max(maxv, f[i - 1][j])
print(max(f[m][j] for j in range(1,n + 1)))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值