Python 所选值的总最大值

Python 所选值的总最大值,python,arrays,algorithm,backtracking,Python,Arrays,Algorithm,Backtracking,问题: 给定一个值数组[a0,a1,a2,…,an] 选择价值观​​根据以下规则: 一次只能取一个值 如果这次已经选择了数组中的第k个值,那么下一轮只能选择从k+1到n-1的值 在奇数转弯处(转弯1,转弯3,…)。选择任意值 在偶数转弯处(转弯2,转弯4,…)。选择与上一个值相同的值 查找并打印我可以选择的值的总最大值 示例: 其中a=[2,5,2,6] 转身1,选择2 第二圈,选择第二个 第三回合,选择第六回合 总最大值为10 其中a=[6,11,14,0,10,1,11,7,

问题:

给定一个值数组[a0,a1,a2,…,an]

  • 选择价值观​​根据以下规则:

    • 一次只能取一个值

    • 如果这次已经选择了数组中的第k个值,那么下一轮只能选择从k+1到n-1的值

    • 在奇数转弯处(转弯1,转弯3,…)。选择任意值

    • 在偶数转弯处(转弯2,转弯4,…)。选择与上一个值相同的值

查找并打印我可以选择的值的总最大值

示例:

其中a=[2,5,2,6]

  • 转身1,选择2

  • 第二圈,选择第二个

  • 第三回合,选择第六回合

    • 总最大值为10
其中a=[6,11,14,0,10,1,11,7,11,11,14,14,13,9,0,12,9,11,3]

  • 总最大值为115
我的代码:

def firstpair(a):
    for i in range(len(a)):
        for j in range(i+1,len(a)):
            if a[i]==a[j]: 
                return [i,j]
    return []
def chooseValues(a):
    s = firstpair(a)
    if len(s)==0: 
        if len(a)==0: return 0
        else: return max(a)
    if s[0]==0: x=0
    else: 
        x = max(a[:s[0]])
    y = a[s[0]]+a[s[1]]+chooseValues(a[s[1]+1:])
    z = chooseValues(a[s[0]+1:])
    return max(x,y,z)

我可以降低上述解决方案的空间复杂度吗?以下是一种思考方法。让
f(i,奇偶性)
表示在奇偶性步骤中选择
i
th元素时达到的最大值。然后:

f(i, even) = A[i] + max(f(j, odd)) // requires O(1) storage
  where j < i and A[j] == A[i]

f(i, odd) = A[i] + max(f(j, even)) // requires O(num_unique_Ai) storage
  where j < i

我认为你可以通过倒转来利用
n
空间和时间复杂性:

def max_value(items):
    best = [0 for _ in items] + [0]
    last_seen = {}

    for i in reversed(xrange(len(items))):
        curr = items[i]
        pair = last_seen.get(curr)
        if pair is None:
            choose_this = curr
        else:
            choose_this = curr * 2 + best[pair + 1]
        best[i] = max(choose_this, best[i + 1])
        last_seen[curr] = i
    return best[0]
如果你想让它复杂一点,你可以通过组合
最后一次看到的
最好的
,用更少的存储空间(与唯一值成比例)来实现:

def max_value(items):
    best_rest = {None: 0}
    best_max = 0

    for i in reversed(range(len(items))):
        curr = items[i]
        choose_this = curr * 2 + best_rest.get(curr, -curr)
        best_rest[curr] = choose_rest = best_max
        best_max = max(choose_this, choose_rest)
    return best_max
在任何一种情况下:

assert max_value([6, 11, 14, 0, 10, 1, 11, 7, 7, 11, 11, 14, 14, 13, 9, 0, 12, 9, 11, 3]) == 115
assert max_value([2, 5, 2, 6]) == 10

具有讽刺意味的是,我们拥有的唯一值越多(超过n/2),我们需要存储的就越少?如果我在你的代码中切换方向,似乎没有什么区别。@,我不得不在脑子里转一转,看看它是否是真的=),不管它是否仍然会尊重原始问题,从右到左进行,这样就可以将它与问题描述和典型的人类尝试进行比较,而不是按照潜在的等效反序。不过,你仍然没有回答我的问题。倒退有什么好处?
assert max_value([6, 11, 14, 0, 10, 1, 11, 7, 7, 11, 11, 14, 14, 13, 9, 0, 12, 9, 11, 3]) == 115
assert max_value([2, 5, 2, 6]) == 10