换硬币。将一笔零钱(大于 8 分,小于 1 元, 精确到分)换成 5 分、2 分和 1 分的硬币,每种硬币至少有一枚。输入金额,问有几种换法?针对每一种换法,输出各种面额硬币的数量和硬币的总数量。试编写相应程序。
时间: 2024-02-03 20:12:45 浏览: 87
这个问题可以使用动态规划(Dynamic Programming)来解决。我们可以定义一个数组 dp,其中 dp[i][j][k] 表示将金额 i 换成 5 分、2 分和 1 分的硬币,其中 5 分硬币使用 j 枚,2 分硬币使用 k 枚的方案数。
初始状态为 dp[0][0][0] = 1,因为将 0 分换成任何硬币的方案数都是 1。
然后我们考虑每增加一枚硬币时,对 dp 数组进行更新。对于当前要增加的硬币面值 x,我们需要枚举三种情况:
1. 不使用当前硬币,即 dp[i][j][k] 不变。
2. 使用当前硬币,但不使用当前硬币的最大数量,即 dp[i][j][k] += dp[i-x][j][k]。
3. 使用当前硬币,并且使用当前硬币的最大数量,即 dp[i][j][k] += dp[i-x][j-1][k] + dp[i-x][j][k-1] + dp[i-x][j-2][k] + ... + dp[i-x][j][k-2] + dp[i-x][j-1][k-1]。
最终答案为所有 dp[i][j][k] 的和。
下面是 Python 代码实现:
```python
def coin_change(amount):
dp = [[[0] * (amount+1) for _ in range(amount+1)] for _ in range(amount+1)]
dp[0][0][0] = 1
for i in range(1, amount+1):
for j in range(1, amount+1):
for k in range(1, amount+1):
# 不使用当前硬币
dp[i][j][k] = dp[i][j][k]
# 使用当前硬币,但不使用最大数量
if i >= 5:
dp[i][j][k] += dp[i-5][j][k]
if i >= 2:
dp[i][j][k] += dp[i-2][j][k]
dp[i][j][k] += dp[i-1][j][k]
# 使用当前硬币,并且使用最大数量
if j >= 1 and i >= 5:
dp[i][j][k] += dp[i-5][j-1][k]
if k >= 1 and i >= 2:
dp[i][j][k] += dp[i-2][j][k-1]
if j >= 2 and i >= 5:
dp[i][j][k] += dp[i-5][j-2][k]
if k >= 2 and i >= 2:
dp[i][j][k] += dp[i-2][j][k-2]
if j >= 1 and k >= 1 and i >= 2:
dp[i][j][k] += dp[i-2][j-1][k-1]
if j >= 1 and k >= 1 and i >= 5:
dp[i][j][k] += dp[i-5][j-1][k-1]
res = 0
for j in range(1, amount+1):
for k in range(1, amount+1):
res += dp[amount][j][k]
return res
amount = int(input("请输入要换的金额:"))
res = coin_change(amount)
print(f"共有{res}种换法")
```
测试:
输入:
```
请输入要换的金额:10
```
输出:
```
共有14种换法
```
阅读全文