您获得 N个整数,A [1]到A [N] 。您必须为这些整数分配权重,使其weighted sum is maximized
。权重应满足以下条件:
加权和定义为S = A [1] * W [1] + A [2] * W [2] + ... + A [N] * W [N]
例如:
n=4 , array[]={ 1 2 3 -4 } , answer = 6 when we assign { 1 2 3 2 } respective weights .
因此,就我的理解和研究而言,没有Greed解决方案是可能的。我用笔在纸上制作了许多测试用例,但无法获得贪婪的策略。
任何想法/提示/接近人。
答案 0 :(得分:1)
通过将权重dp[i][j]
分配给A[1..i]
,j
等于我们可以从A[i]
获得的最大加权和。显然dp[i][j] = j*A[i] + max(dp[i - 1][(j - 1)..N])
。有O(N^2)
个状态,每个州的重复次数为O(N)
,因此整体时间复杂度为O(N^3)
。为了将其减少到O(N^2)
,我们可以注意到我们的重复出现了重大的重叠。
如果dp[i][j] = j * A[i] + max(dp[i - 1][(j - 1)..N])
,那么
dp[i][j - 1] = (j - 1)*A[i] + max(dp[i - 1][(j - 2)..N]) = (j - 1)*A[i] + max(dp[i - 1][j - 2], dp[i - 1][(j - 1)..N]) = (j - 1)*A[i] + max(dp[i - 1][j - 2], dp[i][j] - j*A[i])
这意味着重复只需要O(1)来计算,总体上给你O(N ^ 2)时间。
答案 1 :(得分:0)
不是解决方案,而是一个想法: 我认为某种爬山方法可能会产生很好的效果。
我们可以观察到我们可以提出的“最差”最佳解决方案是
1 2 2 2 2等
也就是说,我们可以分配给不属于索引0
的任何数字的最低权重是2
。因此,我们可以为任何负数分配的最低权重为2
。
这个初始重量分布为我们提供了一个起点。
我敢打赌,我们可以不断修改我们的体重分布,使得总和永远不会减少。也就是说,我们永远不需要暂时获得长期收益。
问题是,我们的迭代策略应该是什么?因为后续权重对以前的权重有一定的依赖性,我们如何迭代?
也许你可以做一些事情,你拿第一个正数并将其增加到最高值,然后对下一个正数和下一个执行相同的操作。
之后,您可以解决序列中的第一对(负,正)数字,同时增加两个数字(如果可能)以查看最终结果是否更好。
然后你执行另一轮递增正数 之后的那个序列,然后找到 next 对(负数,正数),并重复。
答案 2 :(得分:0)
可以使用相当标准的动态编程方法在O(N³)时间内解决这个问题。设V(k,u)表示当Wₖ₋1具有值u时可以使用元素k ... N得到的最佳值。观察到V(k,u)是g·Aₖ+ V(k-1,g)的最大值,因为g的范围是2到u + 1,并且V(N,u)是(u + 1)·如果A N 为正,则 N ,否则为2·A N 。
请注意,在任何V(k,u)计算中u最多为k,因此(k,u)有N *(N-1)/ 2个可能的值,因此概述的方法使用O(N²) )空间和O(N³)时间。
答案 3 :(得分:0)
这是一个小小的洞察力,可以让您或其他人提出一个非常快速的解决方案。请注意,对于最佳解决方案,您可以安全地假设在每个步骤中,您将重量从前一个重量增加+1,或者您将重量一直减少到最小值2.要看到这一点,假设您有违反财产的最佳解决方案。然后你有一些重量> 2在某个位置i-1
,下一个重量也是> 2位于i
但不是增加。现在考虑从位置i
开始的最优解中的最大长度弱增加子序列(弱增加意味着在子序列的每个步骤中,权重不减小)。通过假设,具有该子序列的最优解不比同一解更差,除了从其所有权重中减去1的子序列。但这意味着将子序列中的所有权重增加1也不会使最优解更糟。因此,对于最佳解决方案,在每个步骤中,您可以安全地假设您将重量增加1或将重量设置为最小值2.