📜  来自前缀的最大和递增子序列和前缀后的给定元素必须是(1)

📅  最后修改于: 2023-12-03 15:26:34.559000             🧑  作者: Mango

来自前缀的最大和递增子序列和前缀后的给定元素必须是

介绍

该题目要求在一个数组中,找到以给定元素为结尾的最大和递增子序列。

思路

设 $sum[i]$ 表示以第 $i$ 个元素为结尾的最大和递增子序列的和,$dp[i]$ 表示前缀中以第 $i$ 个元素为结尾的最大和递增子序列的和。

则有转移方程:

$$ sum[i] = max{sum[j] + a[i]}, (1 \le j < i,~a[j] < a[i]) $$

$$ dp[i] = max{dp[j] + a[i]}, (1 \le j < i,~a[j] < a[i],~a[j] < a[k],~k > i) $$

其中,$a$ 表示原始数组。

最后,若存在以给定元素为结尾的递增子序列,则答案为 $sum[i]$。否则,答案为 $dp[i]$。

代码
def max_sum_increasing_subsequence_from_prefix(a, k):

    n = len(a)
    sum = [a[i] for i in range(n)]
    dp = [a[i] for i in range(n)]

    for i in range(1, n):
        for j in range(i):
            if a[j] < a[i]:
                sum[i] = max(sum[i], sum[j] + a[i])
            if a[j] < a[i] and a[j] < a[k] and k > i:
                dp[i] = max(dp[i], dp[j] + a[i])

    if max(a) < a[k]:
        return a[k]
    elif sum[k] > dp[k]:
        return sum[k]
    else:
        return dp[k]
示例
>>> a = [1, 2, 3, 1, 2, 3, 4]
>>> max_sum_increasing_subsequence_from_prefix(a, 6)
10
复杂度

该算法的时间复杂度为 $O(n^2)$,空间复杂度为 $O(n)$。