322. Coin Change零钱兑换问题
1.
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。
示例 1:
输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:
输入: coins = [2], amount = 3
输出: -1
解法:背包问题,首先想最少的硬币数,肯定是尽量取较大的硬币,能取一个则硬币数加一,取当前硬币的个数等于之前硬币个数加上当前这个硬币(也就是加1),但前提是之前硬币总价值加上当前这个硬币的价值不能超过总个数,因此是一个动态规划问题。
状态转移方程:
因此两层循环,外面一层是金额,里面一层是每个硬币。
dp[i]=min(dp[i],dp[i−coin[j]]+1)dp[i]=min(dp[i],dp[i-coin[j]]+1)dp[i]=min(dp[i],dp[i−coin[j]]+1)
class Solution { public: int coinChange(vector<int>& coins, int amount) { vector<int> dp(amount+1,amount+1); dp[0] = 0; for(int i=1;i<=amount;i++){//这里从1开始到<=,是因为第一个数量为0值肯定为0,最后一个数量肯定也要涉及到 for(int j=0;j<coins.size();j++){ if(coins[j]<=i) dp[i] = min(dp[i],dp[i-coins[j]]+1); } } return dp.back()>amount?-1:dp.back(); } };
2.
给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
示例 1:
输入: amount = 5, coins = [1, 2, 5]
输出: 4
解释: 有四种方式可以凑成总金额:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1
示例 2:
输入: amount = 3, coins = [2]
输出: 0
解释: 只用面额2的硬币不能凑成总金额3。
示例 3:
输入: amount = 10, coins = [10]
输出: 1
解题:这道题和上一个非常相似,思想难度也不大,但是有一个坑,就是顺序问题,例如总金额4,121和112都是总金额4,但是要求是无序的,也就是说这两个都是一个情况,所以不能像之前那样考虑,因为外循环金额内循环硬币,121和112都是在最后一个硬币循环遇到的,肯定会重复,怎么不会重复呢?外循环硬币内循环金额就可以了,这是为啥呢?就相当于一个硬币一个硬币的加,每增加一个硬币就从1到amount考虑所有金额,因为硬币是一个一个考虑了,所以就不会重复了。
class Solution { public: int change(int amount, vector<int>& coins) { vector<int> dp(amount+1,0); dp[0] = 1; for(int j=0;j<coins.size();j++){ for(int i=1;i<=amount;i++){ if(coins[j]<=i){ dp[i] += dp[i-coins[j]]; } } } return dp.back(); } };
- 动态规划-背包问题、兑换零钱问题、旅行商问题
- leetcode322---零钱兑换
- 零钱兑换问题
- UVA 674 Coin Change 钱币兑换问题 类似完全背包
- Leetcode 322. 零钱兑换
- LeetCode--Coin Change(兑换零钱)Python
- hdu 1284 钱币兑换问题( 完全背包)
- ACM HDU1284 钱币兑换问题
- leetcode_322 Coin Change
- 钱币兑换问题(完全背包)
- 杭电1284 兑换钱币问题
- hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人
- 找零钱类组合问题思路小结
- HDU 1284 钱币兑换问题
- 最少零钱问题 最少硬币问题
- 找零钱问题
- HDU ACM 1284 钱币兑换问题
- 【POJ2240】Arbitrage 比值最短路 (货币兑换问题)
- L3-001. 凑零钱 01背包 满包问题+记录路径
- 钱币兑换问题 HDU 1284