设有 n 种不同面值的硬币,各硬币的面值存于数组 T[1:n]中。现要用这些 面值的硬币来找钱。可以使用的各种面值的硬币个数存于数组 Coins[1:n]中。 对任意钱数 0≤m≤20001,设计一个用最少硬币找钱 m 的方法。 输入: 输入的第一行中只有 1 个整数给出 n 的值,第 2 行起每行 2 个数,分别 是 T[j]和 Coins[j]。最后 1 行是要找的钱数 m。 输出: 程序运行结束时,将计算出的最少硬币数输出。问题无解时输出-1。使用c++来实现这个代码并列出
时间: 2024-02-19 16:59:21 浏览: 71
好的,以下是使用动态规划实现的 C++ 代码:
```c++
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1005;
const int MAXM = 20005;
int n, m;
int T[MAXN], Coins[MAXN];
int dp[MAXM];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> T[i] >> Coins[i];
}
cin >> m;
memset(dp, INF, sizeof(dp));
dp[0] = 0; // 初始化为 0
for (int i = 1; i <= n; i++) { // 枚举硬币种类
for (int j = T[i]; j <= m; j++) { // 枚举凑出的钱数
if (Coins[i] == 0 || dp[j - T[i]] == INF) {
// 如果硬币数量为 0 或者凑不出 j - T[i] 元钱,则跳过
continue;
}
dp[j] = min(dp[j], dp[j - T[i]] + 1); // 转移
}
}
if (dp[m] == INF) {
cout << -1 << endl; // 无解
} else {
cout << dp[m] << endl; // 输出最少硬币数
}
return 0;
}
```
其中,dp 数组初始化为正无穷,表示无法凑出该钱数,除了 dp[0] 初始化为 0。在枚举硬币种类和钱数时,如果当前硬币数量为 0 或者凑不出 j - T[i] 元钱,则跳过该次循环。最终输出 dp[m] 即可。
阅读全文