leetcode322 Coin Change (动态规划之 凑钱问题 - 1)

凑钱问题可以说是一类非常经典的算法了, 也就是给你一堆相应面额的钱币, 要求用最少的钱币数凑出一个数, 通常会用贪心和动态规划两种算法

用贪心算法的情况一般只有一种, 就是各个面额之间没有公因子的情况, 比如人民币, 就分为1, 5, 20, 50, 100; 这样的话每次就尽量取最大的就好了

可如果像这道题一样, 面额是随机输入的, 比方说我输入的是2, 3那么凑的话就不能按照贪心来凑了

就必须要用到动态规划, 其实这题本身就是一个动态规划中的完全背包问题 (即每一个硬币可以取无限次), 可以参考我写的完全背包题解: https://blog.csdn.net/a1097304791/article/details/83547276

是背包问题就要考虑到对容量的定义, 很显然只能是金额作为容量

注意由于是取最小的数, 所以除了dp[0]之外应该初始化为1<<30

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        if(amount < 0) return -1;
        else if(amount == 0) return 0;
        
        int dp[amount+5]; //凑成i元时的最少硬币数
        dp[0] = 0;
        for(int i = 1; i <= amount; i++)
            dp[i] = 1<<30;
        
        for(int j = 0; j < coins.size(); j++)
            for(int i = 1; i <= amount; i++){
                if(i >= coins[j])
                    dp[i] = min(dp[i], dp[i-coins[j]]+1);
            }
        
        if(dp[amount] > amount) return -1; //特殊条件
        return dp[amount];
        
    }
};

猜你喜欢

转载自blog.csdn.net/a1097304791/article/details/83757914