1.递归+回溯
记录每种钱币能够使用的最大数量,然后遍历每一种情况,求钱币数量最小的,但会超时
2.动态规划
设置dp[amount+1],初始值设为0x3f3f3f3f,即为无穷大
dp[i]表示总量是i是,coins中的金币组成i所需的最小金币个数
此处以钱币为1 2 5,总额是11举例
dp[11]=dp[10]+1,即组成10的最小金币个数加 币值1的个数1
dp[11]=dp[9]+1,即组成9的最小金币个数加 币值2的个数1
dp[11]=dp[6]+1,即组成6的最小金币个数加 币值5的个数1
知dp[11]=min(dp[10],dp[9],dp[6])+1
一般的,对dp[i],遍历coins,当coins[j]<=i,即组成i的最优解可以使用coins[j],有公式:
dp[i]=min(dp[i],dp[i-coins[j]]+1);
若最终dp[i]==0x3f3f3f3f,表示无法使用coins中的金币组成I
代码如下:
class Solution {
int imin=INT_MAX;
int flag=0;
public:
int coinChange(vector<int>& coins, int amount) {
//返回结果组合所需的最小金币个数
if(coins.size()==0 && amount==0)
return 0;
if(coins.size()==0 && amount!=0)
return -1;
sort(coins.begin(),coins.end());
vector<int> dp(amount+1,0x3f3f3f3f);
dp[0]=0;
for(int i=1;i<=amount;i++)
{
for(int j=0;j<coins.size() && coins[j]<=i;j++)
{
dp[i]=min(dp[i],dp[i-coins[j]]+1);
}
}
if(dp[amount]==0x3f3f3f3f)
return -1;
return dp[amount];
}
};