leetcode 322. Coin Change

给定硬币面额和种类,给定总金额,求用最少个数的硬币去组成这个金额

https://leetcode-cn.com/problems/coin-change

和leetcode 518 类似

Example 1:
Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1

Example 2:
Input: coins = [2], amount = 3
Output: -1


1. 这里是问最小的硬币数量,且存在组合不了的情况,所以直接用MAX初始化数组

2. 这里就要初始化dp[0]=0,这里就能够让面额2硬币,对于金额2来说有d[2] = min d[2-2]+1,d[2] = d[0]+1=1

3. 转移方程就是dp[j] = min(dp[j-coins[i]]+1, dp[j]); 这一行左边+1和上一行的最小值

4. 注意是可以一个硬币多用,所以内层循环顺着来(完全背包)

 
如图,对于上面的example1 来说

从左至右更新

背包 0 1 2 3 4 5 6 7 8 9 10 11
初始化 0 - - - - - - - - - - -
1 0 1 2 3 4 5 6 7 8 9 10 11
2 0 1 1 2 2 3 3 4 4 5 5 6
5 0 1 1 2 2 1 2 2 3 3 2 3

所以输出dp[11] = 3
 

class Solution {
public:
    int coinChange(vector<int>& coins,int amount) {
        const int MAX = 0x7fffffff-1;
        int dp[amount+1];
        fill(dp,dp+amount+1,MAX);
        dp[0] = 0;
        int n = coins.size();
        for(int i=0;i<n;i++){
            for(int j=coins[i];j<=amount;j++){
                if(dp[j] !=MAX ||dp[j-coins[i]]!=MAX)
                //上面的dp[j] !=MAX 可以去掉
                    dp[j] = min(dp[j-coins[i]]+1, dp[j]);
            }
        }
        return dp[amount] == MAX? -1:dp[amount];
    }
};












种一棵树最好的时间是十年前,其次是现在。
原文地址:https://www.cnblogs.com/islch/p/12600063.html