最大子序列和問題

最大子序列和問題(Maximum Subsequence Problem)是一個著名的動態規劃問題,它的目標是在一個給定的序列中找到一個子序列,其和最大。這裡的「子序列」是指原始序列中的一些元素,它們保持原始的相鄰關係。例如,在序列 [2, 1, -3, 4, 2] 中,子序列 [2, 1, 4, 2] 是一個合法的子序列,而 [2, 4, 2] 則不是,因為中間的 1 元素沒有被包含。

解決這個問題的動態規劃算法如下:

  1. f[i] 表示以 a[i] 為最後一個元素的最長子序列和,那麼 f[i] = max(f[i-1], 0) + a[i]
  2. 如果 f[i-1] >= 0,那麼 f[i] = f[i-1] + a[i],因為我們可以在上一個子序列後面加上 a[i] 得到一個更大的和。
  3. 如果 f[i-1] < 0,那麼 f[i] = 0 + a[i] = a[i],因為上一個子序列和為負,我們可以捨棄它,從 a[i] 開始構建一個新的子序列。

這樣,我們就可以通過累加的方式來計算每一個位置 i 的最大子序列和。時間複雜度為 O(n),空間複雜度也是 O(n),因為我們需要存儲 f[i] 的值。

以下是一個簡單的Python實現:

def max_subsequence_sum(arr):
    n = len(arr)
    dp = [0] * n  # 動態規劃狀態

    for i in range(n):
        if dp[i-1] >= 0:
            dp[i] = dp[i-1] + arr[i]
        else:
            dp[i] = arr[i]

    # 最後一個元素總是最後一個子序列的結束
    dp[-1] += dp[-2]

    # 找到最大子序列和
    max_sum = dp[0]
    for i in dp:
        max_sum = max(max_sum, i)

    return max_sum

# 測試
arr = [2, 1, -3, 4, 2]
print(max_subsequence_sum(arr))  # 輸出應該是6

這個算法不僅可以找到最大子序列和,還可以找到相應的子序列。只需要在計算過程中記錄每一個 f[i] 的來源位置,就可以在最後回溯得到最大子序列。