问题
How can we find the maximum sum of a non-decreasing sub-sequence in an array using fenwick tree? For example we have 1 4 4 2 2 3 3 1, here the maximum sum of a non-decreasing sub-sequence is 11 (1 2 2 3 3).
回答1:
Maximum sum may be found using a dynamic programming algorithm. Scan the array and for each element add its value to the largest sub-sequence sum which is valid (sub-sequence ends with a value not greater than this element).
Efficient implementation needs some way to quickly find maximum value in given sub-range. Augmented binary search tree may be used to do it. Fenwick tree is just an efficient implementation of augmented binary search tree. Most common use of Fenwick tree is to find a sum of values in some sub-range. Trivial modification allows to use it to find sub-range maximum (this works because in this particular case values in the Fenwick tree are never decreased).
See this Python code for details:
array = [1, 4, 4, 2, 2, 3, 3, 1]
numbers = sorted(set(array))
n = len(numbers)
indexes = {numbers[v]:v+1 for v in range(0, n)}
n += 1
bit = [0] * n
result = 0
for x in array:
pos = indexes[x]
i = pos
maximum = 0
while i != 0:
maximum = max(maximum, bit[i])
i = i & (i-1)
x += maximum
i = pos
while i < n:
bit[i] = max(bit[i], x)
i += i & -i
result = max(result, x)
print(result)
indexes
dictionary is used to decrease size of Fenwick tree from the largest number in the input array to the array's size. First nested while
finds sub-range maximum in Fenwick tree. Second nested while
updates Fenwick tree after one of the sums is updated.
This code works only for an array of positive numbers. In general case input array should be pre-processed by filtering out all non-positive numbers.
Time complexity is O(N log N). Space complexity is O(N).
来源:https://stackoverflow.com/questions/15193469/maximum-sum-of-a-non-decreasing-sub-sequence-in-an-array-using-fenwick-tree-or-b