1. dp数组的含义
下标:需要凑到的钱总和
值:最小需要多少个硬币
2.递推公式
dp[j] = min(dp[j], dp[j - coins[i]] + 1)
不放入 i :dp[j]
放入 i :dp[j - coins[i]] + 1
这里 + 1 表示放入了 i ,所以个数 + 1。和之前加价值不一样,因为dp数组的含义变了
3. 初始化
dp [ 0 ] = 0
凑到 0 ,不需要硬币,所以数量也为 0 ( 这里和之前也不一样
4. 遍历顺序
由于是完全背包, 所以都是顺序遍历
因为求的的硬币的个数,而不是方案的数量,所以嵌套的前后也不会影响
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;
for(int i = 0; i < coins.size(); i++) // 物品
{
for(int j = coins[i]; j <= amount; j++) // 背包
{
// j - coins[i]如果是无穷大,说明无法凑出钱的总和为j - coins[i],
// 也就无法在这个基础上继续推进到 amount
if (dp[j - coins[i]] != INT_MAX)
dp[j] = min(dp[j], dp[j - coins[i]] + 1);
}
}
// 说明无法凑出 钱的总和为 amount
if(dp[amount] == INT_MAX) return -1;
return dp[amount];
}
};