您的位置:首页 > 其它

322. Coin Change零钱兑换问题

2019-04-01 21:02 183 查看

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();
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: