Leetcode 换钱最少货币数

题目描述

给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。

如果无解,请返回-1.

 

输入

复制

[5,2,3],20

输出

复制

4

 

【思路】

经典的dp问题,每一轮研究新的硬币k的加入,能否使得之前组配sum的硬币总数减少

即 dp[sum]=min(dp[sum],dp[sum-k]+1)   ①

注意点:

初始化dp[0]=0  dp[i]=-1 即没有组配方案

sum-k>=0  需要讨论,公式①需要在dp[sum]!=-1情况下,若等于-1 那没得选  dp[sum]=dp[sum-k]+1

 

class Solution {
public:

    int minMoney(vector<int>& arr, int aim) {
        // write code here
        vector<int> dp(aim+1);//dp[i]表示组合成aim最少使用的硬币
        
        for(int i=0;i<aim+1;i++)
            dp[i]=-1;
        if(arr.size()==0 || aim<0)
            return -1;
        
       // sort(arr.begin(),arr.end());//排序
        dp[0]=0;
        for(int i=0;i<arr.size();i++)
        {
            //每一轮研究一组更大面值硬币的加入能否减少硬币使用量
            //分别查看j面值组配方案
            for(int j=1;j<=aim;j++)
            {
                //对于当前研究总额j  如果比j小arr[i]的总额存在组配方案
                //那么当前的dp更新
                if((j-arr[i])>=0 && dp[j-arr[i]]!=-1)  
                {
                    if(dp[j]==-1)
                        dp[j]=dp[j-arr[i]]+1;
                    else
                         dp[j]=min(dp[j],dp[j-arr[i]]+1);
                }
                
            }

        }
        return dp[aim];

    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值