【问题标题】:Maximum sum of non-consecutive elements (with k elements from anywhere)非连续元素的最大总和(来自任何地方的 k 个元素)
【发布时间】:2011-03-29 14:56:50
【问题描述】:

“给定一个正整数数组,从这个数组中找出不连续元素的最有效算法是什么,当它们相加时,会产生最大和?”这个问题的修改版本。标准版回答得很好here

但是,如果您也可以从列表中的 anywhere 中选择指定数量的元素,无论它们是否连续,该怎么办?在这种情况下,您将如何找到最大总和?

举个例子,假设您正在建造房屋。您有 n 个住房地段可供选择。每个地块都有一个与之相关的财务价值,如果你在那里建房子,你将获得 X[i]。但是,由于分区法,您不能在连续的地块上建造(因此,如果您在 #5 地块上建造,则不能在 #4 或 #6 上建造)。您想以最大化价值的方式建造房屋。因此,如果 H[ ] 是您要建造的房屋列表,那么问题将是 H[i] = max ((H(i-1), H(i-2) + X[i])).

但是现在,如果您有额外的 k 分区许可证(其中 k 给您),可以让您在除了固定地块之外的任何地方建造?

【问题讨论】:

  • 选择最大的k。还是我误解了你的问题?
  • K 是固定的,这让我很困惑。帖子已编辑。

标签: arrays algorithm dynamic-programming


【解决方案1】:

这可以通过一个简单的动态规划算法来解决:

  1. 创建一个元组列表(例如tuples);此列表包含两个对象:已建成房屋的总价值,以及选择的房屋地段列表(例如lots
  2. 将列表初始化为一个元素,值为 0 和一个空的手数列表
  3. 遍历所有可能的住房地段。每批L:
  4. 遍历列表:对于列表中的每个元组T
  5. 如果可以将房屋添加到房屋地块列表中(即列表中的地块少于 k,并且添加 L 不会破坏非连续规则),则在列表中创建另一个元素,将T 的值与在此地块上构建的值相加(您将其称为X[i]),并将L 添加到T 中的lots 列表中。
  6. 遍历tuples,找到最大value的那个。房屋地段的最佳选择存储在tuplelots

不确定它的复杂性(n^2*k?- 现在想不出来),但总体来说还不错。

这样做的好处是:通过一些巧妙的编码,您可以将算法重用于任何规则集。只需让第 5 步接受外部条件即可。

【讨论】:

  • 直接的动态规划方法(在每一步都考虑到使用 0
【解决方案2】:

d[i][j] - 动态,如果第一个未使用的房子是i 并且我们已经使用了j 奖金,我们可以拿多少钱。

d[0][0] = 0;  
d[i][j] = max(d[i-1][j], d[i-2][j] + x[i], d[i-1][j-1] + x[i]);

【讨论】:

  • 没有什么比 O(nk) 更好的了?
  • @akappa 我认为没有。因为它与背包问题非常相似——我们不知道哪些物品应该被标记为允许。
  • 是的,但是没有“免费房屋”的问题是 O(n)。我认为有一些关于各种解决方案成本的属性,我们可以利用这些属性来使某些东西更接近 O(n)。
【解决方案3】:

先选择k个最好的元素,然后在没有之前选择的元素的情况下解决“最好的非连续整数”问题。

【讨论】:

  • 我认为该解决方案行不通。例如,假设您有一个 {2, 8, 6, 2, 10, 4} 列表和 k = 1。如果您选择最大值 10,您将获得一个 { 2, 8, 6, 2, x, 4} 列表。剩余列表的最大值将是 8、2 和 4 中的 14。总最大值将为 24。但如果您从原始列表中选择 8,给出{2, x, 6, 2, 10, 4},您可以从 2、6 中获得最大值,和 10,也就是 18。加上前 8 个得到 26。
  • 对。我在考虑这样一个事实,即您的问题的每个最佳解决方案必须包含 k 个最大元素(很容易看出:您通过采用满足“非相邻”约束的解决方案来获得解决方案,并且添加未包括的最大元素)。我认为有一些解决方案巧妙地利用了这一事实,也许是对动态编程方法的改编。
猜你喜欢
  • 2011-05-28
  • 1970-01-01
  • 2020-11-01
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多