我们有一个数组作为生产的输入。
R = [5, 2, 8, 3, 6, 9]
如果选择i
输入,则输出是i
元素的总和,其索引小于i
的最大元素和索引大于{{的最小元素1}}。
例如,如果我取8,则输出为8 + 5 + 3 = 16。
无法再次选择所选项目。因此,如果我选择8,下一个选择的下一个数组将看起来像i
选择总输出最大的所有输入的顺序是什么?如果可能,请发送动态编程解决方案。
答案 0 :(得分:0)
我将使用 O ( n 2 n )解决方案开始竞标。 。
您对问题的描述存在一些含糊之处,您拒绝在评论中提及。这些歧义都不会影响此解决方案的运行时复杂性,但它们确实会影响解决方案的实现细节,因此解决方案必然是草图。
解决方案如下:
创建2个 n 整数的数组results
。每个数组索引i
将表示输入的某个子序列,results[i]
将是我们可以从该子序列开始实现的最大总和。
[5, 2, 8, 3, 6, 9]
,则子序列5 2 8
将表示为数组索引000111 2 = 7,表示results[7]
。 (你也可以从最重要的位开始 - 这可能更直观 - 但是那个映射的实现有点不太方便。由你决定。)然后按顺序进行,从子集#0(空子集)到子集#2 n -1(完整输入),计算每个如果我们选择每个可能的元素并添加相应的先前存储的值,则通过查看我们得到多少来获得array-element。因此,例如,要计算results[7]
(对于子序列5 2 8
),我们选择这些值中最大的值:
results[6]
以及如果我们选择5
results[5]
以及如果我们选择2
results[3]
以及如果我们选择8
现在,它似乎似乎它应该需要 O ( n 2 )时间来计算任何给定的数组元素,因为输入中有 n 元素,我们可以选择,并且如果我们这样做,我们得到多少需要检查所有其他元素(找到先前元素中的最大值,以及之后的最小元素)元件)。但是,我们实际上可以在 O ( n )时间内完成,首先从右向左传递以记录晚于每个元素的最小值。输入,然后从左到右继续尝试每个可能的值。 (两个 O ( n )通过加起来 O ( n )。)
一个重要的警告:我怀疑正确的解决方案只涉及,在每一步,选择最右边或第二到最右边的元素。如果是这样,那么上面的解决方案计算的值比考虑到这一点的算法多得多。例如,索引111000 2 的结果显然与那种情况无关。但我不能证明这种怀疑,所以我将上述 O ( n 2 n )解决方案呈现为我确定的最正确的解决方案。
答案 1 :(得分:0)
(我假设这些要素是非负的,没有相反的建议。)
这是一个基于鲁赫克猜想的O(n ^ 2)时算法,存在一个最优解,其中每个选择来自最右边的两个,我在下面证明。
DP的状态是(1)n
,剩余的元素数(2)k
,最右边元素的索引。我们有一个复发
OPT(n, k) = max(max(R(0), ..., R(n - 2)) + R(n - 1) + R(k) + OPT(n - 1, k),
max(R(0), ..., R(n - 1)) + R(k) + OPT(n - 1, n - 1)),
其中第一行是我们采用第二个最右边的元素,第二行是我们采取最右边的元素。空的最大值为零。基本案例是
OPT(1, k) = R(k)
适用于所有k
。
证明:从最右边的两个元素中选择的条件等同于只有在保留最多i
个元素时才能选择索引i + 2
处的元素(从零开始计数)的限制。我们通过归纳表明,对于i < j
j
是诱导变量的所有j = 0
,存在满足该条件的最优解。
基本情况是微不足道的,因为每个最优解都满足i < j
的空洞限制。在归纳的情况下,假设存在满足所有j
的限制的最优解。如果在剩余j + 2
个元素超过j + 2
时选择了j
,请考虑如果我们推迟该选择会发生什么,直到剩下正好j
个元素为止。归纳假设在此区间内没有选择j
左边的元素,因此它们无关紧要。选择j
右侧的元素只能至少有利可图,因为包括j
不能减少最大值。同时,-Dkey=value
左边的元素集在两个时间都是相同的,java
右边的元素集合在较晚的时间与较早的时间相比是一个子集,所以最小的时间没有减少。我们得出结论,这种推迟不会影响解决方案的盈利能力。