我最近在接受采访时被问到这个问题,
给定一组非负整数找到 可以获得的最大累积总和,使得所有的长度 参与的子阵列是素数。我尝试使用动态编程为此提出解决方案,但遗憾的是不能。
例如:如果数组是[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解决此类问题?感谢。
答案 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_here
与SUBARRAY_SIZE
进行比较。并相应地更新`MAX_SO_FAR_FOR_PRIMES1。