硬币问题(瓜子网二手车试题)

硬币问题(瓜子网二手车试题)

有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n <= 100000),有多少中组合可以组成n分钱?

我只知道使用多重for循环进行暴力求解,效率很低,数字高了后算不出来。

答案中提供了一个很巧妙的方法。但我看不懂。

几经钻研后,搞懂了。主要参考了这篇文章。

# python3
def change(coins, n):
    len1 = len(coins)
    if len1 == 0 and n < 1 or n > 100000:
        return None
    ways = [0] * (n + 1)  # 初始化
    ways[0] = 1
    for i in range(len1):
        for j in range(coins[i], n + 1):
            # 保证n小于等于100000,为了防止溢出,请将答案Mod 1000000007
            ways[j] = (ways[j] + ways[j - coins[i]]) % 1000000007
    print(ways[n])
  
if __name__ == '__main__':
    coins, n = [1, 2, 5, 10], int(input())
    change(coins, n)

我们应该都还记得迈台阶问题。一次性可以迈1-2阶,递推关系如下。

F(N)=F(N-1)+F(N-2)

那么对于硬币问题,也可以视为一次增加1,2,5,10级台阶,最终凑到n阶就可了。

那么是否有:

F(N)=F(N-1)+F(N-2)+F(N-5)+F(10)呢?

当然不是。例如在N-5级台阶的时候,此时到N的方法显然不止一种。甚至可以说是有多种的。因而,也应该要把F(6)等给算上。

因为可以选择的情况太多了,导致上面这种简单的递推关系式就不成立了。

因而我们尝试让任何时候都只有两个选择。从简单的两种硬币1,2开始。

此时显然有:

F(N)=F(N-1)+F(N-2)

F(1)=1

如果只使用硬币1

F(N)=F(N)+F1(N-1)

其中F1是使用当前所有类型的硬币的数目。

如果同时使用2

F(N)=F(N)+F1(N-1)

+F2(N-2)

其中F1来自硬币1,F2来自硬币2

此时如果把硬币5加上。

F(N)=F1(N)+F2(N-5)

每一个点N可以如此构成,只含1的方法个数,只含1,2的方法个数,125方法个数,12510方法个数。

对任何一个F(N)只含一的方法个数一定是1。

含有2的方法个数就是从第一个可以被2更新的点3,每个点F(N)+=F(N-1)

最终还是发现问题描述不清楚。。。该死的。算了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值