最長不下降序列

最長不下降序列(Longest Increasing Subsequence,LIS)是一個在數列中尋找最長的元素序列,且這些元素依序遞增的問題。例如,給定數列 [10, 22, 9, 33, 21, 50, 41],其最長不下降序列為 [9, 21, 33, 41, 50],長度為5。

最長不下降序列問題在許多領域都有應用,例如在生物學中用於比對基因序列,在計算機科學中用於排序和線性複雜度的最短路徑問題,以及在經濟學中用於價格分析等。

解決最長不下降序列問題可以使用動態規劃(Dynamic Programming)的方法。基本思路是將問題分解為較小的子問題,並記錄已經解決的子問題的答案,以避免重複計算。

以下是使用動態規劃解決最長不下降序列問題的算法:

  1. 初始化一個長度與數列相同的數組 lis,用來存儲最長不下降序列的長度。
  2. 對於數列中的每一個元素 nums[i],檢查 nums[i] 是否可以作為最長不下降序列的終點。
  3. 如果 nums[i]nums[0..i-1] 中的所有元素都大,那麼 nums[i] 就可以作為最長不下降序列的終點。
  4. 更新 lis[i] 的值為 lis[0..i-1] 中的最大值加上 1。
  5. 最後,找到 lis 中的最大值,並從數列中找出對應的最長不下降序列。

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

def lis(nums):
    n = len(nums)
    lis = [1] * n  # 初始化最長不下降序列的長度為1
    for i in range(n):
        for j in range(i):
            if nums[i] <= nums[j]:
                lis[i] = max(lis[i], lis[j] + 1)
    return lis, max(lis)

# 示例
nums = [10, 22, 9, 33, 21, 50, 41]
lis_length, max_lis_length = lis(nums)
print(f"The length of the longest increasing subsequence is {max_lis_length}")
print(f"The subsequence is {[nums[i] for i in range(len(nums)) if lis_length[i] == max_lis_length]}")

這個算法的時間複雜度為 O(n^2),空間複雜度為 O(n)。對於較大的數列,可以使用二維數組來優化時間複雜度到 O(n log n),或者使用分治法來達到線性時間複雜度 O(n)