现在有面额分别为1、2、5元的硬币数,总金额11元,计算并返回可以凑成总金额所需的最少硬币个数。若没有组合能组成总金额,则返回-1。给出采用递归法求解的解题思路以及重复计算的次数。使用c语言代码编写
时间: 2024-08-12 12:08:08 浏览: 85
在解决这个问题时,我们可以使用动态规划和递归的方法。动态规划有助于减少重复计算,因为我们可以将子问题的解决方案存储下来,避免再次计算。递归可以帮助我们枚举所有可能的硬币组合。
首先,我们需要定义一个数组 dp,其中 dp[i] 表示用给定的硬币(1元、2元、5元)凑成 i 元所需的最少硬币数。递归的基本思路是:
1. 如果 i 小于1元,那么不可能凑出 i 元,dp[i] = -1。
2. 如果 i 是1、2或5的倍数,那么只用相应面额的硬币即可,dp[i] = 1。
3. 对于其他值,我们需要尝试1元、2元和5元三种情况,并选择使得 dp[i] 最小的那个。
递归函数可能如下(在 C 语言中):
```c
#include <stdio.h>
int minCoins(int coins[], int n, int target) {
int dp[target + 1]; // 初始化dp数组
dp = 0; // 目标为0时,不需要硬币
for (int i = 1; i <= target; ++i) {
dp[i] = INT_MAX; // 初始化为极大值,后续会更新为最小值
for (int j = 0; j < n; ++j) {
if (coins[j] <= i && dp[i - coins[j]] != -1) {
dp[i] = (dp[i] < dp[i - coins[j]] + 1) ? dp[i] : dp[i - coins[j]] + 1;
}
}
}
return dp[target] == INT_MAX ? -1 : dp[target]; // 返回目标值对应的最少硬币数,若无解则返回-1
}
int main() {
int coins[] = {1, 2, 5}; // 硬币数组
int n = sizeof(coins) / sizeof(coins); // 硬币数量
int target = 11; // 总金额
printf("最少硬币数: %d\n", minCoins(coins, n, target));
return 0;
}
```
递归过程中的重复计算主要发生在遍历 dp 数组时,对于每个目标值 i,我们都要检查所有可能的硬币组合。如果 i 可以由多个组合得到,那么这部分就会重复计算。但由于动态规划的使用,重复的计算结果会被记录下来,所以总计算次数会随着问题规模的增加而线性增长,而不是指数级的。
阅读全文