所选值的总最大值

时间:2019-12-03 18:42:59

标签: python arrays algorithm backtracking

问题:

  

给出一个值数组[a0,a1,a2,..,an]

     
      
  • 根据以下规则选择值:

         
        
    • 一圈只能取一个值。

    •   
    • 如果这次已经选择了数组中的第k个值,则下一轮只能选择k + 1至n-1之间的值。

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

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

    •   
  •   
     

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

示例:

  

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

     
      
  • 转1,选择2。

  •   
  • 转到2,选择2。

  •   
  • 转动3,选择6。

         
        
    • 总最大值为10
    •   
  •   
     

a = [6,11,14,0,10,1,11,7,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)

我可以降低上述解决方案的空间复杂度吗?

2 个答案:

答案 0 :(得分:2)

我认为您可以通过倒退来解决torch.from_numpy(np.array(someVar, dtype=np.uint8)) 的时空复杂性:

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] last_seen来减少存储量(与唯一值成比例):

best

无论哪种情况:

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

答案 1 :(得分:0)

这是一种思考方式。令f(i, parity)表示在具有奇偶校验i的步骤中选择第parity个元素时获得的最大值。然后:

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
def f(A):
  max_f_j_even = -float("inf")
  max_f_j_odd = {A[0]: A[0]}
  best = -float("inf")

  for i in range(1, len(A)):
    # Even turn
    new_max_f_j_even = None
    if A[i] in max_f_j_odd:
      new_max_f_j_even = max(max_f_j_even, A[i] + max_f_j_odd[A[i]])

    # Odd turn
    else:
      # A[i] is a first turn
      max_f_j_odd[A[i]] = A[i]

    # A[i] is a later odd turn
    max_f_j_odd[A[i]] = max(max_f_j_odd[A[i]], A[i] + max_f_j_even)

    if new_max_f_j_even != None:
      max_f_j_even = new_max_f_j_even

    best = max(best, max_f_j_even, max_f_j_odd[A[i]])

  return best

A = [2,5,2,6]
print(f(A)) # 10

A = [6,11,14,0,10,1,11,7,7,11,11,14,14,13,9,0,12,9,11,3]
print(f(A)) # 115