問題描述:給出一個數字array(其元素值可正可負),求其連續子序列中,各元素和的最大值(不要求子序列的長度)
定義子狀態:表示以數組元素結尾的最大子序列之和
狀態轉移關係:,或者表示成更簡單的
- 代碼示例
def MaxsumOfSub(array):
# 只需求解最大序列和
m = [0 for _ in range(len(array))] # 狀態數組,記錄當前位置的最大和
m[0] = array[0] # 第一個元素的初值
MaxSum = array[0] # 記錄最大和,也可以得到狀態矩陣後,最後統一求max
for i in range(1, len(array)): # 從第二個元素開始
m[i] = m[i-1] + array[i] if m[i-1]>0 else array[i]
if m[i] > MaxSum:
MaxSum = m[i]
return MaxSum
print(MaxsumOfSub([1,2,3,4])) # 10
print(MaxsumOfSub([1,-1,2,-3,4,-3])) # 4
print(MaxsumOfSub([-2,1,-1,3,-2,5])) # 6
思考:如果除了給出最大和,還要給出對應的子串呢?
解決方案:再構造一個狀態數組,記錄當前位置最大和對應的子串起止位置
def MaxsumOfSub2(array):
# 在需求解最大序列和的同時,還需要記錄子串位置
m = [0 for _ in range(len(array))] # 狀態數組,記錄當前位置的最大和
s = [(0, 0) for _ in range(len(array))] # 狀態數組,記錄當前位置的最大和對應的索引位置
m[0] = array[0] # 第一個元素的初值
MaxSum = array[0] # 記錄最大和
MaxIndex = (0, 0) # 記錄最大和對應的起止索引
for i in range(1, len(array)): # 從第二個元素開始
if m[i-1] > 0:
m[i] = m[i-1] + array[i]
s[i] = (s[i-1][0], i)
else:
m[i] = array[i]
s[i] = (i, i)
if m[i] > MaxSum:
MaxSum = m[i]
MaxIndex = s[i]
return MaxSum, array[MaxIndex[0]: MaxIndex[1]+1]
result, index = MaxsumOfSub2([1,2,3,4])
print(result) # 10
print(index) # [1, 2, 3, 4]
result, index = MaxsumOfSub2([1,-1,2,-3,4,-3])
print(result) # 4
print(index) # [4]
result, index = MaxsumOfSub2([-2,1,-1,3,-2,5])
print(result) # 6
print(index) # [3, -2, 5]