繁体   English   中英

自下而上的方法以最少的硬币数目进行找零

[英]Bottom-up approach to minimum number of coins for change

我正在构建一种自下而上的方法来解决硬币找零问题。 我必须给出要求进行找零所需的最少硬币数量。 由于给定的面额无法形成该值,因此可能无法给出更改。

例如,如果给定的面额为{4,8},并且他们要求更改为5,那么就不可能给出5。我在下面构造了该程序,它在大多数情况下都可以正常使用,除非无法形成所请求的更改。 例如,当面额仅为{4}且我请求5时,它返回一个为假的。 我该怎么做才能解决这个问题?

这里P表示请求的更改,S是从索引0到S-1的数组denominations []中存储的面额数目。dp是用于计算的二维数组,其初始化为-1。

for (int i = 0; i <= P; ++i) {
    for (int j = 0; j < S; ++j) {
        int ans, x, y;

        // Min. no. of coins with current coin
        x = (i - denominations[j] >= 0) ? dp[i - denominations[j]][j] + 1: 0;

        // Min. no. of coins w/o current coin
        y = (j > 0) ? dp[i][j - 1] : 0;

        ans = min(x, y);
        if (ans == 0) ans = max(x, y);
        dp[i][j] = ans;
    }
}

谢谢您的帮助。

该错误是你没有正确操作时,禁止两者使用当前的硬币, 没有使用它的情况。 例如,在您的示例情况下会发生这种情况:当i = 1且j = 0时,我们试图不使用任何硬币或仅使用4c硬币来总计1c; 但是我们无法使用4c硬币来做到这一点,也不能没有4c硬币来做到这一点。

在这种情况下,x和y都将被分配为0,并且if (ans == 0) ans = max(x, y); 旨在阻止任何一种可能性时捕获情况,最终错误地将an分配为0。 因此,外循环的后续迭代将“认为”有可能使相应的总和不产生任何硬币,并巧妙地将其加1,从而为您的示例给出错误的答案1。

我认为,最干净的解决方法是选择一个不同于0的前哨值来表示“此操作是不可能的,不应考虑”。 由于您将两个可能的动作与min()结合在一起,因此自然就可以得出一个极高的值:

#define INF (INT_MAX-1)   // Or anything higher than the biggest sensible answer

for (int i = 0; i <= P; ++i) {
    for (int j = 0; j < S; ++j) {
        int ans, x, y;

        // Min. no. of coins with current coin
        x = (i - denominations[j] >= 0) ? min(INF, dp[i - denominations[j]][j] + 1) : INF;

        // Min. no. of coins w/o current coin
        y = (j > 0) ? dp[i][j - 1] : INF;

        ans = min(x, y);
        dp[i][j] = ans;
    }
}

注意线ans = min(x, y); 现在无需进行进一步的工作即可给出正确的答案,包括应该将其设为INF的情况,因为x和y均为INF

一个更微妙的一点是,当我们读到一些dp[a][b]我们的计算过程中, 该值允许是INF :这是一个合理的值,表明a毛钱不能用硬币的任意组合进行键入<= b 理想情况下,为INF选择的值应具有将其与任何正值相乘或相乘的属性,使它留在INF ,因为那样的话,我们就不必对该算法做任何进一步的调整:对INF值执行的每个操作都将正确地将其留在INF 但是整数算术无法以这种方式工作,因此在将可能是INF的值添加到某个值之后,我们需要检查是否没有“越过无穷大”并进行修正,如果这样:这就是d[i - denominations[j]][j] + 1包装在min(INF, ...)调用中。 (这也是为什么我将INF定义为小于INT_MAX -这样就不会发生溢出。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM