【问题标题】:Recursive algorithm to solve change-making problem解决变更问题的递归算法
【发布时间】:2020-02-03 06:07:19
【问题描述】:

我想制作一个递归算法来解决变更问题。是否可以使用非动态方法,不仅返回最小数量的硬币,还返回用于构成给定值的硬币集合,

例如,给定值 6 和硬币集合=[1, 3, 4]。是否有可能制作一个不记忆的递归算法,可以返回最小硬币数量(2)和硬币集合(3,3)?

编辑:这是我目前的算法,但它只返回硬币的总数:

int makeChangeRecursive(int[] coins, int numCoins, int amount)
   int r, l;
   if (A == 0) return 0;
   else if (n == -1 || A < 0) return -1;
   r = makeChangeRecursive(coins, numCoins - 1, amount);
   l = 1 + makeChangeRecursive(coins, numCoins, amount - coins[numCoins]);
   if (r == -1 && l == 0) return -1;
   else if ((r == -1 || l < r) && l != 0) return l;
   return r;

makeChangeRecursive({1, 2, 5}, 2, 11);

会返回 3,但我希望它也提供集合 {5,5,1}。第二个参数 (2) 是硬币的数量减 1。

【问题讨论】:

  • 如果你有一套硬币,你真的需要硬币的数量吗?毕竟,您应该能够只获得集合中的项目数。
  • 我的问题是从递归算法中找出集合。我可以找到硬币的总数,但不能自己生成。

标签: algorithm recursion coin-change


【解决方案1】:

是的,这是可能的,而且非常简单。

你只需要考虑你返回的元素:这里是int,是struct (int + history) 以及聚合您的“返回”值的函数:这​​里是总和 (1 + int)-&gt;int 以跟踪历史修改

int -> 1 + int
// becomes
(int, history) -> (int+1, history + pieceTaken)

考虑结构

struct NbCoin {
  int nbCoin;
  vector<int> history; // array of pieces you took during recursion
}

//now makeChangeRecursive returns the number of coin AND history
NbCoin makeChangeRecursive(int[] coins, int numCoins, int amount)
    int r, l;
    if (A == 0) return { nbCoin: 0, history: []}; //like before but with the empty history
    else if (n == -1 || A < 0) return { nbCoin: -1, history: []}; // idem

    // now contains our history as well
    r = makeChangeRecursive(coins, numCoins - 1, amount);

    // here you are taking some coin, so track it into history
    l = makeChangeRecursive(coins, numCoins, amount - coins[numCoins]);
    l = { 
      nbCoin: 1 + l.nbCoin, // like before
      history : l.history.concat(coins[numCoins]) // pieceTaken is coins[numCoins]
      // concat should create a __new__ array merging l.history and coins[numCoins]
    }

    // put nbCoin everywhere as our comparison key
    if (r.nbCoin == -1 && l.nbCoin == 0) return { nbCoin: -1, []};
    else if ((r.nbCoin == -1 || l.nbCoin < r.nbCoin) && l.nbCoin != 0) return l;
    return r;

makeChangeRecursive({1, 2, 5}, 2, 11);

在您管理硬币数量的任何地方,您都可以管理struct.nbCoin,并同时更新历史记录。

我没有检查你的算法是否正常,相信你。

我修改的代码现在不是java有效的,由你来实现!

【讨论】: