给定面值分别为2,5,7的硬币,每种硬币有无限个,给定一个n,求组成n最少需要的硬币的数量,若无法组成则返回-1.
时间: 2023-04-23 13:05:24 浏览: 233
这道题目可以使用动态规划来解决。我们可以定义一个数组dp,其中dp[i]表示组成i最少需要的硬币数量。初始时,dp[0]=0,因为组成0不需要任何硬币。
接下来,我们考虑如何更新dp数组。对于每个i,我们可以枚举使用哪种硬币,然后更新dp[i]。具体地,我们可以枚举使用面值为2的硬币,此时需要的硬币数量为dp[i-2]+1;枚举使用面值为5的硬币,此时需要的硬币数量为dp[i-5]+1;枚举使用面值为7的硬币,此时需要的硬币数量为dp[i-7]+1。最终,dp[i]的值就是上述三种情况中的最小值。
最后,如果dp[n]的值为无穷大,则说明无法组成n,返回-1;否则,返回dp[n]的值即可。
下面是Python代码实现:
def coinChange(n: int) -> int:
dp = [float('inf')] * (n + 1)
dp[0] = 0
for i in range(1, n + 1):
if i >= 2:
dp[i] = min(dp[i], dp[i - 2] + 1)
if i >= 5:
dp[i] = min(dp[i], dp[i - 5] + 1)
if i >= 7:
dp[i] = min(dp[i], dp[i - 7] + 1)
return dp[n] if dp[n] != float('inf') else -1
相关问题
有1分,2分,5分,10分四种硬币,每种硬币数量无限,给定n分钱(n<100000),有多少中组合可以组成n分钱?
这是一个比较经典的动态规划问题,可以使用动态规划算法来解决。
首先,我们定义一个一维数组 dp,其中 dp[i] 表示组成 i 分钱所需的硬币组合数。因为每种硬币数量无限,所以在计算 dp[i] 时,我们需要考虑使用当前硬币和不使用当前硬币两种情况。
对于第一种情况,即使用当前硬币,那么组成 i 分钱的组合数就等于组成 i-coin 分钱的组合数加上当前硬币的一种组合数,其中 coin 表示当前硬币的面值。
对于第二种情况,即不使用当前硬币,那么组成 i 分钱的组合数就等于组成 i 分钱的组合数。
因此,我们可以得到状态转移方程:
```
dp[i] = dp[i] + dp[i-coin]
```
其中,coin 可以取 1 分、2 分、5 分、10 分这四种硬币。
最终,dp[n] 就是组成 n 分钱的组合数。
以下是 Python 代码实现:
```python
def coinChange(n):
coins = [1, 2, 5, 10]
dp = [0] * (n+1)
dp[0] = 1
for coin in coins:
for i in range(coin, n+1):
dp[i] += dp[i-coin]
return dp[n]
```
这个算法的时间复杂度是 O(n),可以在较短的时间内得到结果。
设有6 种不同面值的硬币,各硬币的面值分别为5 分,1 角,2 角,5 角,1 元,2元。现要用这些面值的硬币来购物。在购物中希望使用最少个数硬币。例如,1 次购物需要付款0.55 元,如果没有5 角的硬币,只好用2x2角+1x1角+1x5分 共4 枚硬币来付款。 对于给定的各种面值的硬币个数和付款金额,计算使用硬币个数最少的交易方案。 输入格式: 输入数据有若干组,第一行给出一个整数n表示输入数据的组数。 以下n行每一行有6 个整数和1个有2 位小数的实数。分别表示可以使用的各种面值的硬币个数和付款金额。 输出格式: 输出每组数据的最少硬币个数。如果不可能完成交易,则输出“impossible”。 python实现
可以使用动态规划来解决这个问题。
具体的,设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。
阅读全文