【问题标题】:Jumps in sequence with max gain - Dynamic Programming以最大增益顺序跳跃 - 动态规划
【发布时间】:2017-04-09 22:27:14
【问题描述】:

我们有一个项目序列 1、...、n,每个项目都有一个分数(i)。如果我们选择一个项目,那么我们就不能选择 i+1, ... i+rest(i) 个项目。目标是最大化总分。

我们可以通过动态规划来解决这个问题。

对于第一项,我们有两个选择。或者选择它并转到其余(1)+ 1项或不选择它并转到第二项。

递归函数:

c[i] = max{ c[i - 1], c[i + rest(i) + 1] + score(i) }

这个递归函数的问题是它在子问题之间创建循环,这意味着子问题不是独立的。

我认为最好有类似的东西

c[i] = max{ c[i - 1], c[i - itemThatWentToItem(i)] + score(i) }

也许一个解决方案是有一个函数,它给出导致第 i 项的所有项目,然后取它们之间的最高分。

另一个想法是将这个问题转化为 DAG 中的最长路径,并对所有子图执行此操作。

有什么想法吗?

【问题讨论】:

  • 从头算起:c[i] = max{ c[i + 1], c[i + rest(i) + 1] + score(i) }
  • 愚蠢的问题,但我可以在递归函数中做到这一点吗?最终的解决方案也是 c[0]?

标签: algorithm recursion dynamic-programming


【解决方案1】:

添加到评论。是的,它可以通过递归来实现,例如:

def C(i, n):
  if i > n:
    return 0
  return max(C(i+1, n), C(i+rest(i)+1)+score(i))
print C(0,n)

最好(最快)从后面计算值。喜欢(注意:数组的索引从 1 到 n):

# initialize array with lot of zeros: length + max score(i)
cs = [0] * (n+max(rest(i) for i in range(0,n)+1)
for i in range(n, 0, -1):
  cs[i] = max(cs[i+1], cs[i+rest(i)+1]+score(i))
print cs[1]

【讨论】:

  • 谢谢!知道我理解得更好。我认为从理论/数学的角度来看,你不能从头开始计算它。没有理由:)。
  • 一般来说,在递归函数中,我可以选择 c[i - 1] 或 c[i + 1](取决于问题),对吧?
  • 想法是通过解决更简单的类似子问题来解决问题。在这种情况下,最简单的子问题是最后一个元素,因为它不影响任何其他元素,只有一个组合。然后最后两个元素,有两种组合……所以从后面解决起来比较容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-27
  • 2017-04-26
  • 1970-01-01
  • 2010-12-16
  • 2016-05-02
  • 2012-10-25
相关资源
最近更新 更多