【LeetCode 322】 Coin Change

题目描述

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

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

Note:

You may assume that you have an infinite number of each kind of coin.

思路

写了半天,写了个三层循环。。。
和 【LeetCode 416】 Partition Equal Subset Sum 都是从数组中取一些数字,组成target,不同的是,这个题目每个数字可以取无数次。
动态规划,dp[i]表示组成i需要的最少硬币数,枚举所有硬币,对每个硬币 i,枚举amount j,枚举当前amount可以放下当前硬币的个数k,遍历k,dp[j] = min(dp[j], dp[j-k*coins[i]]),也就是对每个硬币,更新所有的amount,是否能得到较小值。
换个角度,因为可以取无数次,枚举每个硬币i, 枚举amount j ,对每个amount 得到可由前i个硬币组成的最小硬币数。对于硬币 i+1, dp[j] = min(dp[j], dp[j-coins[i+1]]+1),从小到大更新,更新到了取当前硬币的所有可能的个数。

感觉好神奇啊。。。三层循环突然变成二层循环,竟然是一个意思。。。

代码

三层循环

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        if (amount == 0) return 0;
        
        int n = coins.size();
        vector<int> dp(amount+1, INT_MAX/2);
        
        for (int i=0; i<n; ++i) {
            if (coins[i] > amount) continue;
            dp[coins[i]] = 1;
        }
        
        dp[0] = 0;
        for (int i=1; i<=amount; ++i) {
            for (int j=0; j<n; ++j) {
                if (i <= coins[j]) continue;
                int cnt = i/coins[j];
                for (int k=0; k<=cnt; ++k) {
                    dp[i] = min(dp[i], k + dp[i-coins[j]*k]);
                }
            }
        }
        
        return dp[amount] == INT_MAX/2 ? -1 : dp[amount];
    }
};

二层循环

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        if (amount == 0) return 0;
        
        int n = coins.size();
        vector<int> dp(amount+1, INT_MAX/2);
        
        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);
            }
        }
        return dp[amount] == INT_MAX/2 ? -1 : dp[amount];
    }
};

也是一道一年前做过的题。。。。。

发布了243 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/iCode_girl/article/details/104464950
今日推荐