用c++完成以下问题:蒜头君最近在设计一款找钱系统,但它设计的系统比较奇葩。假如有 n 种硬币,每种硬币面值用 ai 表示,并且数量不限。该系统会根据你要找的金额 m,从而找到最少使用硬币的数量以及该数量下的方案总数。
时间: 2023-05-11 11:04:56 浏览: 182
c++钱的问题
这个问题可以使用动态规划来解决。我们可以定义一个数组 dp,其中 dp[i] 表示找 i 元钱所需的最少硬币数量。初始化 dp[0] 为 0,其余为正无穷大。然后我们遍历硬币面值数组 ai,对于每个面值,我们更新 dp 数组。具体地,对于每个 i,我们枚举使用该面值的硬币数量 j,然后更新 dp[i] = min(dp[i], dp[i - j * ai] + j)。同时,我们还需要记录方案总数,可以使用一个数组 cnt,其中 cnt[i] 表示找 i 元钱所需的最少硬币数量对应的方案总数。更新 cnt[i] 时,我们需要考虑使用哪些面值的硬币,具体地,对于每个 i 和每个面值 ai,我们枚举使用该面值的硬币数量 j,然后更新 cnt[i] += cnt[i - j * ai]。最终答案为 dp[m] 和 cnt[m]。
以下是 C 代码实现:
```c
#include <stdio.h>
#include <limits.h>
#define MAXN 1000005
int ai[MAXN];
int dp[MAXN];
int cnt[MAXN];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%d", &ai[i]);
}
for (int i = 1; i <= m; i++) {
dp[i] = INT_MAX;
cnt[i] = 0;
for (int j = 0; j < n; j++) {
if (i >= ai[j] && dp[i - ai[j]] != INT_MAX && dp[i - ai[j]] + 1 < dp[i]) {
dp[i] = dp[i - ai[j]] + 1;
cnt[i] = cnt[i - ai[j]] + cnt[ai[j]];
} else if (i == ai[j]) {
dp[i] = 1;
cnt[i] = cnt[ai[j]] + 1;
}
}
}
printf("%d %d\n", dp[m], cnt[m]);
return 0;
}
```
注意,这个算法的时间复杂度为 O(nm),可能会超时,需要进行优化。
阅读全文