零钱兑换
前言:
这是力扣上的一道题,用的是动态规划,因为自己顿悟,所以想记录一下,如果有什么错误,请大家指教!
题目:
代码:
class Solution {
public:
int change(int amount, vector<int>& coins) {
vector<int> dp(amount+1,0);
dp[0] = 1;
for(int coin:coins)
{
for(int j = 1;j<=amount;j++)
{
if(j >= coin)
{
dp[j] += dp[j-coin];
}
}
}
return dp[amount];
}
};
分析:
- dp的序号也就是当前的总金额,dp的值就是组成当前总金额的组合数。
- 首先 总金额为0 设为1 是为了后面可以计算每种金额由一枚自己金额大小的硬币组合(例如2元可以由一枚2元硬币组成,即2+0 = 2)。
- 每一次循环的内部语句的意思都是:例如 coin=2 , dp[5] = dp[5] + dp[3]意思是当前coin可取0-2组合成5元的所有情况 = coin取0-1组合成5的所有情况 + 一枚2元coin加上coin取0-2组合成3的所有情况。
- 而且 第一次coin=1循环,可以确定总金额为1 的所有组合数为1,因为总金额为1不可能被大于1的coin组成;然后一次类推 coin = n 就可以确定总金额为 n 的所有组合数。