【问题标题】:C finding the lesser difference between two stacksC找到两个堆栈之间的较小差异
【发布时间】:2014-02-21 10:56:17
【问题描述】:

如果我有两个stacks,我必须将来自array 的元素放入其中,并且我必须找到一种递归方式来放入符合规则的元素,即找到两者之和之间的较小差异两个堆栈...

像这样:

values[5] ={1,2,3,4,5}

Stack1 = 4,3

Stack2 = 5,2,1

or 

Stack2 = 4,3

Stack1 = 5,2,1
Difference = between 1 and 2  = 1

你能帮我找到一种递归方式吗?或者至少知道怎么做?

【问题讨论】:

  • 你的意思是最小化两个堆栈之间差异的方法吗?元素入栈的顺序和数组的顺序一样吗?​​
  • 是的,所以两个数组之间的差异是 0 或接近 0,并且顺序无关紧要,因为它是一个尝试所有解决方案的递归问题......

标签: c algorithm recursion


【解决方案1】:

这基本上是 partition problem,即NP-Complete
您正在尝试将 w 数组拆分为两个子集(在您的情况下为堆栈,无关紧要),以便它们的总和在最佳情况下相等,或尽可能接近它。

没有已知的多项式解决方案,但如果数字是相当小的整数 - 有一个很好的 dynamic programming solution 可以快速解决它。

贪心方法(将总和较低的最高元素放入堆栈中,然后重复)是一种近似,在最坏的情况下会比最佳解决方案差|SUM|/2

编辑:动态编程方法本质上是递归的:

base:
f(0,i) = true
f(x,0) = false    (x > 0)
step:
f(x,i) = f(x-arr[i],i-1) OR f(x,i-1)

使用f(SUM/2,n) 调用以查找是否存在最佳解决方案。
现在想想:

  1. 如果f(SUM/2,n) = false,您如何从中找到“最接近”的解决方案?
  2. 如何修改此解决方案,同时为您提供所需解决方案的索引,而不仅仅是布尔答案?

注意:

  • 另一种递归方法是检查所有可能的子集 数组(其中有 2^n 个),然后选择一个 最小化到|SUM|/2的差异

【讨论】:

  • OP 要求递归执行,所以手头的问题可能是练习编程技术而不是降低计算复杂度。
  • @barakmanos 动态编程本质上是一种递归,您将其构建为自下而上的优化,但它背后有递归方法。
  • 据我所知,动态规划本质上是迭代的(以 LCS 的解决方案为例)。
  • @barakmanos 自下而上的 DP 出于效率的原因是通过迭代完成的,但它正在实现一种递归方法,将问题拆分为更小的子问题,计算每个更小的子问题,并做额外的步骤来计算当前较大的问题。这与递归解决方案的想法完全相同。
  • 谢谢你的回答,但你能给我一些伪代码或接近真实代码的东西,这样我就可以看看我是否接近使用递归而不是 DP 的解决方案?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 2021-03-22
  • 1970-01-01
  • 2014-08-15
  • 2022-11-01
相关资源
最近更新 更多