递归:步骤数最少

时间:2019-09-11 10:44:38

标签: javascript node.js recursion

我必须编写一个递归程序来解决此问题:

您得到两个空桶的“ a”升和“ b”升,它们都在海边。 在一个水桶中隔离出“ c”升水所需的最少步骤数量是什么?

给出“ a”,“ b”和“ c”将返回最少的步骤。

我试图以一种简单的方式来做到这一点,我不能在这里应用递归。

function steps(a,b,c){
let s = 0;
let aLimit = 0;
let bLimit = 0;

if (a + b < c){
    for (let l = 0; l < (a + b); l++){
        s += 1;
        aLimit += 1;
        if(aLimit == a){
            s+=1;
        }
        console.log(s);
    }
}

1 个答案:

答案 0 :(得分:0)

我不知道这是否正确,但也许这只是一个开始。 (请注意,如果gcd(a, b)不除c,这可能会永远递归,如果c等于ab,可能会返回意外结果。)我认为math-based答案可能会更有效。

function f(a, b, c, steps=0, aState=0, bState=0, memo={}){
  const key = [aState, bState]
  // Solution found
  if (key.includes(c))
    return memo[key] = steps
  // Already visited 
  if (memo.hasOwnProperty(key))
    return memo[key]
  // Mark as visited
  memo[key] = steps
    
  const aFree = a - aState
  const bFree = b - bState

  return steps + Math.min(
    // pour a to b
    aState ? f(a, b, c, steps + 1, Math.max(0, aState - bFree), Math.min(aState + bState, b), memo) : Infinity,
    // pour b to a
    bState ? f(a, b, c, steps + 1, Math.min(aState + bState, a), Math.max(0, bState - aFree), memo) : Infinity,
    // fill and pour a to b
    f(a, b, c, steps + 1, Math.max(0, a - bFree), Math.min(a + bState, b), memo),
    // fill and pour b to a
    f(a, b, c, steps + 1, Math.min(aState + b, a), Math.max(0, b - aFree), memo)
  )
}

console.log(f(3, 5, 4))