递归解决换零钱问题

本文通过递归分析探讨如何解决用特定面额的零钱(如50元、20元等)兑换100元的方式总数。首先,问题被形式化为caseOfChange函数,接着分析基本情形(base case)和递归情形(recursive case)。在递归情形中,将问题拆分为使用特定面额(如50元)和不使用的情况,通过递归逐步解决。最后,通过手动演算验证递归模式,并讨论了金额为0和负数的情况。
摘要由CSDN通过智能技术生成

以下是我们的问题:

把100元用50元,20元,10元,5元,1元去换,总共有几种换法?

形式化(formalize)



为了简化叙述,把问题记为“coc(100, [50, 20, 10, 5, 1])”。

coc: case of change或者count of change(change在英文中有零钱的意思)

为使问题更具有一般性,参数化具体值,得到:

caseOfChange(amount, cashList)

其中amount为金额,cashList为零钱列表。

递归分析



前面说到递归分两种情形,一是 基本情形(base case) ,二是 递归情形(recursive case)

基本情形(base case)

显然,问题难在零钱种类太多,如果只有一种零钱,问题就简单了:

比如coc(100, [50])=1,即有一种换法,也就是换成2张50的。

又如coc(50, [20])=0,即没法换,2张20不够,3张又太多。

显然,结果不是0就是1,就看能否整除。根据以上分析,得出:

caseOfChange(amount, cashList) {
    // base case
    if (cashList.containsOnlyOneCash()) { // 只有一种零钱时
        if (amount.canBeChangedWith(cashList.getTheOnlyOneCash())) { // 能换时,即能整除
            return 1;
        } else {
            return 0;
        }
    } else {
        // recursive case, TODO
    }
}

注:暂时请只专注于描述我们的问题,现在还不急着考虑具体的实现。

递归情形(recursive case)

因为递归的模式并不是那么明显,我们还是先回到传统的思路上考虑。

拆分问题

问题难在零钱种类太多,我们首先考虑能否拆解它。

把大问题分成几个小问题,或者说把一个复杂问题分成几个简单问题,这是我们常用的伎俩。

那么怎么分解呢?我们经常能想到的就是一分为二。

如果我们能找到一种方法,比方说,能把5种零钱拆成“1+4”,那么“1”可以在base case中解决了,更进一步,4又可拆成1+3,循环往复,问题就可解决了。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值