📜  最大化不属于最长递增子序列的所有元素的总和(1)

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

最大化不属于最长递增子序列的所有元素的总和

在某些情况下,我们需要找到一个序列中不属于最长递增子序列的所有元素,并将它们的总和最大化。这个问题被称为最大化不属于最长递增子序列的所有元素的总和。在本文中,我们将讨论如何解决这个问题。

问题描述

给定一个长度为n的序列a1,a2,......,an,找到一个子序列b1,b2,......,bk,其中b1 < b2 < ...... < bk,且b1,b2,......,bk不是序列a1,a2,......,an的最长递增子序列。我们需要最大化所有不属于这个子序列的元素a[i]的和。

例如,对于序列[1, 7, 2, 8, 3, 4],最长递增子序列是[1, 2, 3, 4],不属于最长递增子序列的元素是[7, 8]。因此,最大化不属于最长递增子序列的所有元素的总和的结果是15(7 + 8)。

解决方案

为了解决这个问题,我们可以使用动态规划。首先,我们需要找到最长递增子序列。

最长递增子序列

我们可以使用动态规划来找到最长递增子序列。设d[i]表示以a[i]为结尾的最长递增子序列长度,则有:

$$ d[i]=\max_{j<i,a_j<a_i}{d[j]}+1 $$

其中,$a_j<a_i$表示a[j]可以和a[i]构成递增序列。这个算法的时间复杂度为O(n^2)。为了优化时间复杂度,我们可以使用二分查找来寻找j,将时间复杂度优化为O(nlogn)。具体算法可以参考最长递增子序列问题的多种解法

最大化不属于最长递增子序列的元素的总和

设f[i]表示不包含a[i]的最大化总和,则有:

$$ f[i]=\max_{j<i,a_j<a_i}{f[j]}+a_i $$

其中,$a_j<a_i$表示a[j]可以和a[i]构成递增序列。这个算法的时间复杂度为O(n^2)。同样地,我们也可以使用二分查找来优化时间复杂度。

对于最终的结果,我们可以通过对f数组求最大值来得到。

代码实现

下面是使用Python实现的代码片段:

def max_exclude_lis_sum(a):
    n = len(a)
    d = [1] * n
    for i in range(1, n):
        for j in range(i):
            if a[j] < a[i]:
                d[i] = max(d[i], d[j] + 1)

    lis = []
    mx = max(d)
    for i in range(n - 1, -1, -1):
        if d[i] == mx:
            lis.append(a[i])
            mx -= 1
    lis = lis[::-1]

    f = [0] * n
    for i in range(n):
        f[i] = a[i]
        for j in range(i):
            if a[j] < a[i] and f[j] > f[i]:
                f[i] = f[j]
        f[i] += a[i]

    ans = 0
    for i in range(n):
        if a[i] not in lis:
            ans = max(ans, f[i])

    return ans
总结

本文介绍了如何解决最大化不属于最长递增子序列的所有元素的总和的问题。通过使用动态规划和二分查找,我们可以将时间复杂度优化到O(nlogn)。