COLCOIN-收集硬币

时间:2019-05-30 07:17:27

标签: algorithm greedy

我正在解决此问题-COLCOIN-在spoj上收集硬币。 链接-https://www.spoj.com/problems/COLCOIN/

对于给定的一组面额和所需的货币,银行会为您提供面额最大的硬币,直到不再存在为止,然后转移到下一个面额最大的硬币。例如:如果面额为[1,2,3,4,8],如果您要求23卢比,它将首先给您两个8卢比硬币,并且由于不能再提供8卢比硬币,请移至下一个面额,给你一四卢比和一三卢比。

问题是找到给定面额输入可获得的最大不同面额数量。您从银行要求的钱是一个变量,如果我是正确的话,它实际上不应该出现在图中。

这是我的主意:

尝试总结小面额的价值,看看它们是否可以总计成更大的面额,如果是的话,您将永远不会获得所有较小的面额。

ex:假设有1、2和5。1 + 2 <5.这样就可以得到所有面额。 8 = 5 + 2 + 1

另一个:假设有3,4和5面额。因此3 + 4> 5因此,我们永远无法获得所有面额。因为将以5面额的面额提供货币,直到应支付的面额少于5为止。显然,如果您的货币少于5,则无法获得3 + 4 = 7卢比

另一个显然是错误的想法是从第二高的面额开始,找到要加到上面的硬币,然后返回该解决方案+1(最高面额)。 这是不正确的,因为例如[1,2,4,17,19],如果我们已经将19数了,试图将18求和,则得到1 + 17,只有2个面额,而26会给四个面额19 + 4 + 2 + 1

1 个答案:

答案 0 :(得分:0)

我认为您可以使用以下方法:

  1. 从最低面额开始
  2. 检查添加的下一个最低面额是否超过此后的面额
    1. 如果总和较小,则将面额添加到总和中
    2. 否则继续并检查一步的面额是否不超过此后的面额。

例如:1 3 6 8 15 20

  1. 不同面额d = 1,总和= 1
  2. 1 + 3 <6:d = 2,总和= 4
  3. 4 + 6> = 8:d = 2,总和= 4
  4. 4 + 8 <15:d = 3,和= 12
  5. 12 + 15> = 20:d = 3,总和= 12
  6. 12 + 20 <无限:d = 4,总和= 32

=>答案为4(提款金额为32)。

实施:

// expects the denominations to be ordered from smallest to largest
// and also expects them to be unique
function findMaxDenominationsInSingleWithdrawal(denominations) {
    if (denominations.length <= 2)
        return denominations.length
    let sum = denominations[0], d = 1
    for (let index = 1; index + 1 < denominations.length; index++) {
        if (sum + denominations[index] < denominations[index + 1]) {
            d++
            sum += denominations[index]
        }
    }
    return d + 1
}

console.log(findMaxDenominationsInSingleWithdrawal([1, 3, 6, 8, 15, 20]))