从数组中查找元素,使得没有两个相邻且其总和最大

时间:2018-05-09 13:21:26

标签: algorithm

找到一个包含给定数组元素的序列,这样就不会有两个元素相邻,我们需要最大化所形成序列的总和。

输入: - {4,1,3,4}

输出: - 4 4

1 个答案:

答案 0 :(得分:0)

这是一个python代码

a = [4, 1, 3, 4]
bestSeq = []
seq = []

def solve(i):
    global maxSum, bestSeq
    if i >= len(a):
        if sum(seq) > sum(bestSeq):
            # Copy Current sequence into best sequence if sum is greater than maxSum
            bestSeq = seq[:]
    else:
        # Include the current element and go to i +2
        seq.append(a[i])
        solve(i + 2)
        seq.pop()

        # Skip the current element and go to i+1
        solve(i + 1)


solve(0)
print(bestSeq)

您必须选择当前数组元素并转到i + 2(因为下一个索引将与此相邻)或者您可以跳过添加当前元素并转到i + 1。在数组中的每个索引处递归执行此操作。

如果索引大于n,则停止并将当前seq与已经bestSeq进行比较,如果总和更大,则保存当前序列。

使用动态编程进行优化

import time
import random
random.seed(19950406)

a = [random.randint(0, 100) for i in range(40)]
DP = [[] for i in a]  # This will hold bestSeq from i, initially empty
seq = []

def solveDP(i):
    global DP

    if i >= len(a):
        return []

    # If this value is already computed return that value
    if len(DP[i]) > 0:
        return DP[i]

    # Include the current element and go to i +2
    arr1 = [a[i]] + solveDP(i + 2)
    # Skip the current element and go to i+1
    arr2 = solveDP(i + 1)
    if sum(arr1) > sum(arr2):
        DP[i] = arr1[:]    # Copy arr1 into DP[i]
    else:
        DP[i] = arr2[:]    # Copy arr2 into DP[i]
    return DP[i]

# Main
start = time.time()
print(solveDP(0))
print("Time Taken : {:.6f}".format(time.time() - start))

输出

[88, 26, 100, 63, 31, 98, 61, 15, 76, 31, 69, 72, 81, 29, 61, 84, 44, 81]
Time Taken : 0.000000

正如您所看到的,动态编程版本比传统的递归解决方案快得多。但是对于非常大的n值(10 ^ 6及更高)

,内存将非常大