牛客题霸 [ 换钱的最少货币数] C++题解/答案

题目描述

给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
如果无解,请返回-1.
【要求】
时间复杂度O(n×aim),空间复杂度On。

题解:

经典dp问题
我们考虑一下当然价值x由什么组成?
x可以由上一个状态x-arr[i]加上第i’个货币arr[i]组成
也就是dp[x]=dp[x-arr[i]]+1
这个+1也就是代表多用了一个货币(因为题目问的是最少货币数,所以dp[x]表示的是x元所用的最少货币数)
因为arr有多个,所以dp取最小值(记得dp要初始化为最大,但是dp[0]=0)
dp[j]=min(dp[j],dp[j-arr[i]]+1);
最后如果dp[aim]没被改变(还是最大化),说明无法表示aim,即返回-1
否则返回dp[aim]

代码:

class Solution {
   
public:
    /** * 最少货币数 * @param arr int整型vector the array * @param aim int整型 the target * @return int整型 */
    int minMoney(vector<int>& arr, int aim) {
   
        // write code here
        if(aim==0)return 0;
        vector<int>dp(aim+1,0x3f3f3f);
        dp[0]=0;
        for(int i=0;i<arr.size();i++)
        {
   
            for(int j=arr[i];j<=aim;j++)
            {
   
                dp[j]=min(dp[j],dp[j-arr[i]]+1);
            }
        }
        if(dp[aim]==0x3f3f3f)return -1;
        else return dp[aim];
    }
};