素数长度的所有连续子阵列的最大总和

时间:2017-03-02 08:16:37

标签: algorithm dynamic-programming

我最近在接受采访时被问到这个问题,

  

给定一组非负整数找到   可以获得的最大累积总和,使得所有的长度   参与的子阵列是素数。我尝试使用动态编程为此提出解决方案,但遗憾的是不能。

例如:如果数组是[9,8,7,6,5,4,3,1,2,2],它应该返回 46 (子阵列的总和 [长度为7的长度为9,8,7,6,5,4,3] ,长度为2的 [2,2] 。你不能将[9,8,7,6,5,4,3]和[1,2,2]结合起来,因为它会导致长度为10的连续子阵列(幂等),这是非素数。

任何人都可以解释如何使用DP解决此类问题?感谢。

3 个答案:

答案 0 :(得分:1)

你能做什么:

  • 取出列表的长度并返回,直到找到素数
  • 获取一个元素窗口并总结它们
  • 检查它是否是最大金额,如果是,请将其存储
  • 转到下一个窗口

这是因为所有整数都是正面的约束,否则它将不起作用。

基本上是这样的(非常粗略,在伪python中,显然没有经过测试):

input_list = (8, 1, 3, 4, 5, 2)
list_size = len(input_list)

while (list_size):
    if (is_prime(list_size)):
        window_size = list_size
        break
    list_size--

max_sum = -1
for i in xrange(0, list_size - window_size):
    current_sum = sum(input_list[i:i+window_size])
    if (max_sum < current_sum):
        max_sum = current_sum

print max_sum

答案 1 :(得分:1)

这样的事情(大约)O(n * n / log n)时间,O(n)空间,DP?

f(i)代表索引i的最大总和,其中a[i]从连续子集中排除,或者是素数长度子集的最后一个。然后:

f(i) = sum(a[0]...a[i]) if (i + 1) is prime, otherwise
  max(
    // a[i] excluded
    f(i-1),
    f(i-2),

    // a[i] is last of a subset
    sum(a[i - primes[j] + 1]...a[i]) + f(i - primes[j] - 1) 
      for primes[j] <= i
  )

(可以在O(1)时间内对{~1}}时间进行求和,并对前缀和进行O(n)预处理。)

答案 2 :(得分:0)

由于其他人已经解决了非负整数的问题。

但是如果你也有-ve数字,那么这个算法也会起作用。 我认为你必须略微调整Kadane's Algo

以下是修改过的Kadane's Algo的变化。所有标记为**的行都是变化。

Initialize:
    max_so_far = 0
    max_ending_here = 0
   ** MAX_SO_FAR_FOR_PRIMES =0
   ** SUB_ARRAY_SIZE = 0

Loop for each element of the array
   max_ending_here = max_ending_here + a[i]
   ** SUB_ARRAY_SIZE = SUB_ARRAY_SIZE + 1 // since a[i] included in subarray, increase sub_array_size
  if(max_ending_here < 0)
            max_ending_here = 0
   **         SUB_ARRAY_SIZE = 0  
  if(max_so_far < max_ending_here)
            max_so_far = max_ending_here
   ** if(MAX_SO_FAR_FOR_PRIMES < max_ending_here && isPrime(SUB_ARRAY_SIZE)) // comparing when SUB_ARRAY_SIZE is Prime.
   **      MAX_SO_FAR_FOR_PRIMES = max_ending_here.    

return MAX_SO_FAR_FOR_PRIMES

基本上,再取一个变量MAX_SO_FAR_FOR_PRIMES,它保留了目前为止大小的子数组的最大和子数组。

还存储SUB_ARRAY_SIZE,它在循环期间随时存储子数组的大小。

现在,只要MAX_SO_FAR_FOR_PRIMES为素数,就会将max_ending_hereSUBARRAY_SIZE进行比较。并相应地更新`MAX_SO_FAR_FOR_PRIMES1。