找零钱
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
//使用动态规划算法,对于贪心算法必须保证这些是倍数增长的所以没有必要进行贪心策略
//必须使用动态规划算法进行相应的计算
int len= coins.size();
vector<int> dp(amount+1,-1);
dp[0]=0;
//开始遍历每一次的硬币数
for(int i=1;i<=amount;++i)//每次的总面额是多少1,2,3,4,5,6,7,8
{
dp[i]=amount+1;
for(int j=0;j<len;++j)//每次的遍历的硬币值1,2,5,10
{
//表示的是当前的总数能用某个硬币来组成,并且保证减去这个硬币之前的面额可以组成
if(i-coins[j]>=0&&dp[i-coins[j]]!=-1)
{
dp[i]=dp[i]<dp[i-coins[j]]+1?dp[i]:dp[i-coins[j]]+1;
}
}
}
int result=dp[amount]==amount+1?-1:dp[amount];
return result;
}
};
7.18日修改代码
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
//使用动态规划算法,对于贪心算法必须保证这些是倍数增长的所以没有必要进行贪心策略
//必须使用动态规划算法进行相应的计算
int len= coins.size();
if(amount==0)
return 0;
vector<int> dp(amount+1,0);
for(int i=1;i<=amount;++i)//每次的总面额是多少1,2,3,4,5,6,7,8
{
//dp[i]=amount+1;
for(int j=0;j<len;++j)//每次的遍历的硬币值1,2,5,10
{
//表示的是当前的总数能用某个硬币来组成并且保证减去这个硬币之前的面额可以组成
if (i - coins[j] == 0)
dp[i] = 1;
if(i-coins[j]>0)
{
if(dp[i-coins[j]]!=0)//这一步保证的是减去当前硬币之后,以前的这种硬币结果必须存在
if(dp[i]==0||dp[i]>dp[i-coins[j]]+1)
dp[i]=dp[i-coins[j]]+1;
}
}
}
cout<<dp[amount]<<endl;
int result=dp[amount]!=0?dp[amount]:-1;
return result;
}
};
这种问题是典型的背包问题,但是与背包问题不同的是,背包问题不需要保证前面的某个结果一定存在一个解,但是对于硬币问题来说因为硬币总和必须是给定的数额所以必须对前面的结果是否存在进行判定