Leetcode 322. 518 零钱兑换 I II 动态规划
322:
/* * @lc app=leetcode.cn id=322 lang=cpp * * [322] 零钱兑换 * * https://leetcode-cn.com/problems/coin-change/description/ * * algorithms * Medium (43.17%) * Likes: 1242 * Dislikes: 0 * Total Accepted: 220.9K * Total Submissions: 510.7K * Testcase Example: '[1,2,5]\n11' * * 给定不同面额的硬币 coins 和一个总金额 * amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 * * 你可以认为每种硬币的数量是无限的。 * * * * 示例 1: * * * 输入:coins = [1, 2, 5], amount = 11 * 输出:3 * 解释:11 = 5 + 5 + 1 * * 示例 2: * * * 输入:coins = [2], amount = 3 * 输出:-1 * * 示例 3: * * * 输入:coins = [1], amount = 0 * 输出:0 * * * 示例 4: * * * 输入:coins = [1], amount = 1 * 输出:1 * * * 示例 5: * * * 输入:coins = [1], amount = 2 * 输出:2 * * * * * 提示: * * * 1 * 1 * 0 * * */
思路:
使用一维数组记录dp[i]钱数为i时的最小硬币数,然后遍历,dp[i]=min(dp[i],dp[i-coins[j]]+1)
base状况为dp[0]=0,总金额为0时需要0枚硬币
class Solution { public: int coinChange(vector<int>& coins, int amount) { int n=coins.size(); vector<int> dp(amount+1,amount+1); dp[0]=0; for(int i=1;i<=amount;++i){ for(int j=0;j<n;++j){ if(i>=coins[j]) dp[i]=min(dp[i],dp[i-coins[j]]+1); } } return dp[amount]>amount?-1:dp[amount]; } };
II:
思路:labuladong
dp[i][j]表示使用到i种硬币,达到j金额,有几种方法。所以状态转移时,如果不放入coins[i-1],则为dp[i-1][j]种,如果放入coins[i-1],则为dp[i][j-coins[i-1]]。
base状况为j=0时dp[i][0]=1,金额为0时,只有一种可能
class Solution { public: int change(int amount, vector<int>& coins) { int n=coins.size(); vector<vector<int>> dp(n+1,vector<int>(amount+1,0)); for(int i=0;i<=n;++i) dp[i][0]=1; for(int i=1;i<=n;++i){ for(int j=1;j<=amount;++j){ if(j<coins[i-1]) dp[i][j]=dp[i-1][j]; else { dp[i][j]=dp[i-1][j]+dp[i][j-coins[i-1]]; } } } return dp[n][amount]; } };
联系方式:emhhbmdfbGlhbmcxOTkxQDEyNi5jb20=