(动态规划)322.零钱兑换

本文探讨了如何利用动态规划算法解决硬币找零问题,即计算给定金额下最少硬币数量。通过分析问题特性,设计了动态规划算法,并给出了具体实现代码,最后讨论了代码中关键细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

还几天没有更新博客,是不是想我了(自恋狂哈哈)。这几天主要是老板让研究pointnet,因为环境配置总是出些问题,(菜鸡一枚)所以耽搁了些时间。搞好了环境,然后看了几天pointnet代码,于是赶快来刷刷题。今天看的仍然是一道动态规划的题目。

题目

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1:

输入: coins = [1, 2, 5], amount = 11
输出: 3
解释: 11 = 5 + 5 + 1
示例 2:

输入: coins = [2], amount = 3
输出: -1

解析

个人通过刷题,发现了一个小问题,这种求最多最小的一般都可以用动态规划来解题,当然这是特殊情况,具体的还要根据动态规划的定义去判定。这题根据定义来看,确实是动态规划的题。我为了图省事,我通常判别动态规划题一般看问题,要求最少最多八九不离十就是动态规划题,然后看是否有最优子结构,如果有,我就把它当做动态规划来解。
对于动态规划问题,我的解法是把问题设为dp[n],然后去找迭代方程。
此题dp[n]就是金额为n时最少的硬币个数,
n<0,dp[n]=-1;
n=0,dp[n]=0;
n>0,dp[n]=min(dp[n],dp[n-c]+1)

代码

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
vector<int> dp(amount+1,INT_MAX/2);//为什么使用INT_MAX/2,而不是INT_MAX
dp[0]=0;//dp[i]表示总金额为i时,所需的最少硬币个数
//类似于01背包问题
for(auto c:coins)
{
    for(int i=c;i<=amount;i++)
    {
        dp[i]=min(dp[i],dp[i-c]+1);//两种情况,总金额包含c面值和总金额不包含c面值,取其中较小值
    }
}
if(dp[amount]==INT_MAX/2)//总金额为amount的dp仍为初始化值,说明没有任何一种硬币组合组成总金额
{
    return -1;
}
return dp[amount];
    }
};

备注

1.为什么使用INT_MAX/2,而不是INT_MAX
因为如果dp[i-c]为INT_MAX时,加上1就会越界
2.动态规划有个特点就是求最小时,初始化的值一般为不越界的情况尽可能大;求最大时,初始化一般为0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值