我遇到的问题可以简化为:
给定
N
个正数的数组,找到具有最小和的精确K
元素的非连续序列。好的:只报告总和。奖励:可以识别拾取的元素(至少有一组索引,如果很多可以实现相同的总和)。
(以外行人的术语:从N值中挑选任何K 非相邻元素,使其总和最小)
当然,2*K <= N+1
(否则无法解决),问题对正/负不敏感(只需将数组值移至MIN=min(A...)
,然后将K*MIN
添加回K+2
回答)。
到目前为止(天真的方法):
K=2
索引。我不确定这一点,因为K>2
这似乎是涵盖所有特定案例的必要条件,但我不知道K+2
**是否需要/足够 (K+1)*(K+2)
就足够了,我可以强制执行K+2
解决方案空间,但正如我所说。我不确定K>2
对于2*K
是否足够(如果事实上C(2*K, K)
点是必要的,那么暴力破坏会超出窗口 - 二项式系数K=2
过度增长快)如何以最小的时间/空间复杂度完成这项工作的任何聪明的想法?
对于[4,1,0,1,4,3,4]
, ** ,这是一个非常重要的例子,其中最接近绝对最小值的4个值是选择目标总和0
所必需的 - 一个不能使用{ {1}}用于构建最小和的值,因为它打破了非连续性标准。
PS - 如果您想要显示代码片段,C / C ++和/或Java将会受到赞赏,但任何具有良好语法或伪代码的语言都会做(我认为“体面的语法”不包括Perl,不会不是吗?)
答案 0 :(得分:3)
假设输入数字存储在数组a [N]
中通用方法是DP:f(n,k)= min(f(n-1,k),f(n-2,k-1)+ a [n])
需要O(N * K)时间并有2个选项:
在大K的特殊情况下,还有另一种可能性:
这样,对于K~ = N / 2,你的时间比O(N K)更低,类似于O(N log(N))。对于小K,它将增加到O(N * log(N) K log(K)),因此一般方法或特殊情况算法之间的决定很重要。
答案 1 :(得分:2)
应该采用动态编程方法。
从左到右沿阵列工作。在每个点i,对于来自1..k的j的每个值,找到从1..i中挑选j个非连续元素的正确答案的值。您可以通过查看i-1,i-2的答案和array [i]的值来计算出答案。你想要的答案是n的答案,长度为n的数组。完成此操作后,您应该能够通过沿阵列的反向跟踪来确定元素是什么,以确定每个点的最佳决策是否涉及在该点选择数组元素,因此是否使用数组[i -1] [k]或数组[i-2] [k-1]。