Leetcode-322-零钱兑换(类完全背包)
题目链接
题目描述
一个整数数组 coins ,表示不同面额的硬币;
以及一个整数 amount ,表示总金额。
计算可以凑成总金额所需的 最少的硬币个数 。
如果没有任何一种组合能组成总金额,返回 -1 。
每种硬币的数量是无限的。
样例
输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1
思路
- 首先想到的时 完全背包问题, 仔细想想又不完全是。
- 完全背包,是求 最多能装的价值是多少,而本题求的是 最少硬币个数。
- dp[j] 表示总和为 j 时,最少的硬币个数。
- 硬币的面额看作体积,每个硬币的价值看作1,背包大小为(amount)。
- \(dp[j] = min(dp[j], dp[j-coins[i]]+1);\)
- dp[] 初始为无限大。若无法和为j, 则dp[j]永远等于无限大
C++代码
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
// dp[j] 表示总和为 j 时,最少的硬币个数。
int n = coins.size();
int cnt = 0, ans = 10001;
vector<int> dp(amount+1, 10001);
dp[0] = 0;
for (int i = 0; i < n; i++)
for (int j = coins[i]; j <= amount; j++)
dp[j] = min(dp[j], dp[j-coins[i]]+1);
if (dp[amount] != 10001)
return dp[amount];
return -1;
}
};