设有n 种不同面值的硬币,各硬币的面值存于数组T[1:n]中。现要用这些面值的硬币来找钱。可以使用的各种面值的硬币个数存于数组Coins[1:n]中。 对任意钱数0≤m≤20001,设计一个用最少硬币找钱m的方法。
时间: 2023-10-23 15:12:45 浏览: 205
这个问题可以用动态规划来解决。设f(i)表示找i元钱所需的最少硬币数量,则有状态转移方程:
f(i) = min{f(i-T[j])+1},其中T[j]表示第j种硬币的面值,且T[j]<=i且Coins[j]>0。
初始状态:f(0)=0,即找0元钱不需要任何硬币。
最终答案为f(m)。
下面是C++代码实现:
```c++
const int INF = 0x3f3f3f3f; // 定义无穷大
int f[20005]; // f[i]表示找i元钱所需的最少硬币数量
int T[105], Coins[105]; // T数组存储硬币面值,Coins数组存储硬币个数
int solve(int m, int n) {
memset(f, INF, sizeof(f)); // 初始化为无穷大
f[0] = 0; // 找0元钱不需要任何硬币
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (T[j] <= i && Coins[j] > 0) {
f[i] = min(f[i], f[i-T[j]]+1);
Coins[j]--; // 使用了第j种硬币
}
}
for (int j = 1; j <= n; j++) {
if (T[j] <= i) {
Coins[j]++; // 恢复第j种硬币的个数
}
}
}
if (f[m] == INF) return -1; // 无解的情况
else return f[m];
}
```
其中m表示需要找的钱数,n表示硬币的种类数。函数返回值为最少硬币数量,若无解则返回-1。
阅读全文