设有6 种不同面值的硬币,各硬币的面值分别为5 分,1 角,2 角,5 角,1 元,2元。现要用这些面值的硬币来购物。在购物中希望使用最少个数硬币。例如,1 次购物需要付款0.55 元,如果没有5 角的硬币,只好用2x2角+1x1角+1x5分 共4 枚硬币来付款。 对于给定的各种面值的硬币个数和付款金额,计算使用硬币个数最少的交易方案。 输入格式: 输入数据有若干组,第一行给出一个整数n表示输入数据的组数。 以下n行每一行有6 个整数和1个有2 位小数的实数。分别表示可以使用的各种面值的硬币个数和付款金额。 输出格式: 输出每组数据的最少硬币个数。如果不可能完成交易,则输出“impossible”。 python实现
时间: 2023-11-28 18:49:51 浏览: 179
可以使用动态规划来解决这个问题。
具体的,设dp[i]表示付款金额为i时所需硬币的最小数量,则有状态转移方程:
dp[i] = min(dp[i], dp[i - coins[j]] + 1)
其中coins[j]表示第j种硬币的面值,dp[i - coins[j]]表示付款金额为i - coins[j]时所需硬币的最小数量。
最终的答案即为dp[payment],其中payment为需要付款的金额。
需要注意的是,如果存在无法完成交易的情况,即付款金额无法被硬币的面值凑出来,此时dp[payment]为无穷大,输出"impossible"。
具体实现见下:
```python
n = int(input()) # 输入数据组数
for _ in range(n):
coins = list(map(int, input().split())) # 各种硬币的数量
payment = int(input() * 100) # 需要付款的金额,单位为分
# 初始化dp数组,全部设为无穷大
dp = [float('inf')] * (payment + 1)
dp[0] = 0
# 动态规划求解最小硬币数
for i in range(payment + 1):
for j in range(6):
if coins[j] > 0 and i >= j + 1:
dp[i] = min(dp[i], dp[i - j - 1] + 1)
# 输出结果
if dp[payment] == float('inf'):
print("impossible")
else:
print(dp[payment])
```
注意在输入需要付款的金额时,需要将其转换为整数,并将单位由元转换为分。同时需要注意数组下标的计算,硬币面值为j + 1,而不是j。
阅读全文