跳至主要內容

钱币找零问题

侯小月,杜玉玉大约 2 分钟教学文档动态规划

钱币找零问题

1. 题目描述

给定不同面值的纸币数量(1元、2元、5元、10元、20元、50元、100元)分别为c0, c1, c2, c3, c4, c5, c6张,以及一个目标支付金额K元。需要计算并输出为了支付K元至少需要使用多少张纸币。

输入:

一个整数K,表示需要支付的总金额(单位:元)。 七个整数c0, c1, c2, c3, c4, c5, c6,分别代表1元、2元、5元、10元、20元、50元、100元纸币的数量。

输出:

一个整数,表示支付K元所需的最少纸币数量。如果无法恰好支付K元,则输出-1。

样例输入: K = 97 c0 = 1, c1 = 2, c2 = 1, c3 = 0, c4 = 3, c5 = 0, c6 = 1 样例输出:

8

2. 分析

此问题可以通过动态规划或回溯法解决。由于每种面值的纸币数量有限,直接应用贪心算法可能得不到最优解。因此,我们选择动态规划方法,该方法能确保找到全局最优解,并且在实现上较为直观。

动态规划:我们需要构建一个数组dp,其中dp[i]表示支付i元所需的最少纸币数量。初始化时,dp[0] = 0,因为支付0元不需要任何纸币。对于每个i从1到K,我们会遍历所有可用的纸币面值,尝试更新dp[i]为min(dp[i], dp[i - coin_value] + 1),前提是coin_value不超过i且还有剩余的该面值纸币。为了考虑到每种面值纸币的数量限制,我们在更新dp[i]时还需要检查是否超过了该面值纸币的最大可用数量。

3. 代码

def min_coins_to_pay(K, coins):
    # Initialize the dp array with infinity, except dp[0] = 0
    dp = [float('inf')] * (K + 1)
    dp[0] = 0
    
    # coins is a list of tuples (value, count) for each coin type
    # Iterate over each amount from 1 to K
    for i in range(1, K + 1):
        for value, count in coins:
            for j in range(1, min(count + 1, i // value + 1)):
                if value * j <= i and dp[i - value * j] != float('inf'):
                    dp[i] = min(dp[i], dp[i - value * j] + j)
    
    return dp[K] if dp[K] != float('inf') else -1

# Example usage:
# Suppose we have the following coins: 1x1, 2x2, 5x1, 10x0, 20x3, 50x0, 100x1
# And we want to pay 97 yuan.
coins = [(1, 1), (2, 2), (5, 1), (10, 0), (20, 3), (50, 0), (100, 1)]
K = 97
print("Minimum number of coins needed:", min_coins_to_pay(K, coins))
上次编辑于:
贡献者: duyuyu123,zilizhou